在書寫邏輯之前,先釐清程式要達成的需求是什麼?
login-wrapper
是登入組件用的,chat-wrapper
則是訊息列表組件,使用 isShow
作為變數來切換判斷。
當然,玩家登入時輸入的名稱,也必須使用 v-model 來雙向綁定,同時進入時則觸發對應的函式。
<div id="app">
// login component
<div v-if="isShow" class="login-wrapper">
<input v-model="username" class="login-input" type="text" />
<button @click="logingChat()">Go Chat</button>
</div>
// chat component
<div v-else class="chat-wrapper">
<h2>Hello : {{ username }}</h2>
<div>
<input v-model="message" class="input-message" type="text" />
<button type="button" class="send-btn" @click="sendMessage()">
Send Message
</button>
<ul class="message-wrapper">
<li v-for="(item, index) in list" :key="index + item">
{{ item }}
</li>
</ul>
</div>
</div>
</div>
data 需要放入上面談到的變數
data: {
// ...
username: '',
isShow: true,
},
當玩家輸入名稱後,點擊觸發登入的函式,先做第一步檢查,避免玩家在未輸入名稱的狀況下也進行登入。
接著,再給 server-side 送出資料時的格式,添加一個事件,進行判斷這是登入的資料還是送出訊息的資料,並使用 JSON.stringify()
來處理。
methods: {
logingChat() {
if (this.username.trim() === '') {
alert('請輸入姓名');
return;
}
this.isShow = false;
this.ws.send(
JSON.stringify({
event: 'login',
message: this.username,
})
);
},
sendMessage() {
this.list.push(this.message);
this.ws.send(
JSON.stringify({
event: 'message',
message: this.message,
})
);
this.message = '';
},
}
至於監聽訊息的部分,因為需要顯示出每個玩家登入時的訊息,所以也透過事件判斷來顯示。
onMessage(event) {
let obj = JSON.parse(event.data);
if (obj.event === 'login') {
this.list.push(`Welcome ${obj.message} enter chat!`);
} else {
this.list.push(obj.message);
}
},