之二來處理一下介面
要讓sidebar跟上面的分頁共用同個組件channels
<div class="sidebar_sec channel">
<div class="title">
<i class="fas fa-chevron-down"></i>channel
</div>
<div class="sidebar_sec_content">
<channels />
</div>
</div>
<div
class="chat_main"
ref="chat_main"
>
<div class="channel_tab">
<channels />
</div>
<div
class="chat_content"
ref="chat_content"
>
<div v-if="channels.now">
<div
v-for="chat in channels.now.msg" //這邊聊天訊息要改成抓目前的channel裡的msg,不然之後切換channel會發現內容沒換
:key="chat.key + chat.text"
>
<component
:is="chat.codeClass"
:text="chat.text"
:name="chat.name"
@scrollBottom="scrollBottom"
/>
// ...
<template>
<ul>
<li
v-for="channel in channels.list"
:key="channel.channelId"
@click="changeChat(channel)"
:class="{'active': channel.channelId === channels.now.channelId}" // 顯示目前在哪個channel
>
{{channel.name}}
<i class="fas fa-times"></i> // 保留做刪除channel的icon,目前也純裝飾用,覺得fontawesome的有點粗...可以自己寫~
</li>
</ul>
</template>
雖然兩個樣式看起來不一樣,但可以藉由外層的class去決定component最後的樣式,一個外層是channel_tab,一個是sidebar_sec_content
.channel_tab {
background-color: $grayBgLight;
ul {
display: flex;
list-style: none;
}
li {
background-color: $grayTab;
padding: 4px 12px;
cursor: pointer;
&.active {
background-color: $grayBg;
}
}
}
.sidebar_sec_content {
li {
cursor: pointer;
&.active {
background-color: $grayBgLightHover;
}
}
}
接著因為在前篇已經把資料都存在store裡,所以channel資料就從store拿,不使用prop的方式取得
<script>
import { mapState, mapMutations } from 'vuex'
export default {
name: 'channel',
computed: {
list() {
return Object.values(this.channels.list) // 取得channel list並轉成array
},
...mapState({
channels: state => state.channels // 取得store的channel資料
})
},
methods: {
changeChat(channel) {
this.SET_NOW_CHANNE(channel) // 切換channel
},
...mapMutations({
SET_NOW_CHANNE: 'SET_NOW_CHANNE' // 取得mutation
})
}
}
</script>
這邊會用到Object.values
將物件轉換成陣列其實可做可不做,v-for一樣可以把object渲染出來,不過先這樣做是有想說如果有調整順序之類的需求,就先轉成陣列這樣~~
這有點久之前寫的,剛花了一點時間回想我幹嘛這樣寫(其實是忘記Object.values是啥)
之後想要做更換聊天室名稱,就可以直接在channel component直接做,一次做兩邊好~棒!(*´∀`)~♥
最後,在page> chat裡
mounted() {
this.$refs.textInput.focus() // focus到input
if (!this.channels.list.length) { // 判斷channel列表是不是空的
const newChannel = {
channelId: 'all',
name: 'undefined',
msg: []
}
this.SET_CHANNEL(newChannel) // 設定新的channel到store
}
這樣設定完,在進入聊天室的時候,channel列表就會有預設的第一個囉~tab也會出現一個~!
這邊沒有通知socket去新增channel,因為預設第一個channel就是聊天大廳,全部線上的人都可以收到訊息,在socket傳訊息的時候就直接全部廣播就好,不用特別去做也沒關係
下一篇就會針對新開的私人聊天做socket訊息傳遞囉~ヽ(∀゚ )人(゚∀゚)人( ゚∀)人(∀゚ )人(゚∀゚)人( ゚∀)ノ
今天寫好多喔~(每天都重點誤 (不要打我
我也覺得我hen棒
鼓勵你拍拍手~~~
我又寫好兩篇囉~(挺胸)
但其實這幾天的扣我幾乎都寫好惹只是在寫文