JavaScript はとても難解です。それを理解しないとリアルタイムチャットはできないと思います。
コピペで動くのでそのまま使おうとしたのですが、そうすると全然応用がききません。
まずは、chat.blade.php で
<div class="px-4 py-3 bg-gray-200 border-t border-gray-300"> <chat-form v-on:messagesent="addMessage" :user="{{ auth()->user() }}"></chat-form></div>
<chat-form>
コンポーネントが書かれている。
ChatForm.vue の
function sendMessage(e) { if (newMessage.value === '') return;
emit("messagesent", { user: props.user, content: newMessage.value });
newMessage.value = "";}
が呼ばれます。
emit("messagesent", { user: props.user, content: newMessage.value })
という部分で、
messagesent というカスタムイベントを発火(親コンポーネントにデータを渡す)。親コンポーネントとは chat.js のことです。
.component('chat-form', ChatForm)
window.Echo.private('chat') .listen('MessageSent', (e) => { messages.value.push({ content: e.message.content, user: e.user });});
function addMessage(message) { messages.value.push(message);
axios.post('/messages', message).then(response => { });}
<chat-form>
を登録し、messagesent イベントをリッスン。
以上が chatGPT の説明です。
import { createApp, ref, onMounted } from 'vue';import axios from 'axios';
// Vue アプリの作成createApp({ setup() { const messages = ref([]); const newMessage = ref(''); const user = ref({ id: 1, name: "自分" }); // 仮のユーザー情報
// メッセージ取得 const fetchMessages = () => { axios.get('/messages').then(response => { messages.value = response.data.map(msg => ({ content: msg.content, user: msg.user })); }); };
// メッセージ送信 const sendMessage = () => { if (newMessage.value === '') return;
const message = { user: user.value, content: newMessage.value };
messages.value.push(message); newMessage.value = '';
axios.post('/messages', message); };
// Pusher 経由でリアルタイム更新 onMounted(() => { fetchMessages();
window.Echo.private('chat').listen('MessageSent', (e) => { messages.value.push({ content: e.message.content, user: e.user }); }); });
return { messages, newMessage, user, sendMessage }; },
template: ` <div class="container"> <!-- メッセージ一覧 --> <ul class="list-group mb-3"> <li v-for="message in messages" :key="message.id" :class="message.user.id === user.id ? 'text-end' : 'text-start'"> <strong> <span v-if="message.user.id === user.id">私</span> <span v-else>{{ message.user.name }}さん</span> </strong> <p>{{ message.content }}</p> </li> </ul>
<!-- メッセージ入力フォーム --> <div class="input-group"> <input type="text" class="form-control" v-model="newMessage" @keydown.enter="sendMessage" placeholder="メッセージを入力..." /> <button class="btn btn-primary" @click="sendMessage">送信</button> </div> </div> `}).mount('#app');
コードが長いとわかりにくくなるので、vue ファイルに分離するんでしょうね。
でも、JavaScript って本当に難解です。