iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 26
0
Modern Web

每日挖個坑,用坑填起耍廢聊天室!系列 第 26

二十六號坑,來做多個聊天頻道之二(介面篇)

https://ithelp.ithome.com.tw/upload/images/20191012/20111962mAW5nQ1Sce.png
之二來處理一下介面

要讓sidebar跟上面的分頁共用同個組件channels

  • sidebar
<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>
  • page > chat 多插入channel_tab區域
<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"
          />
       // ...
  • channels component
    @click="changeChat(channel)" // 點channel更換目前所在的channel
<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 MDN

這有點久之前寫的,剛花了一點時間回想我幹嘛這樣寫(其實是忘記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訊息傳遞囉~ヽ(∀゚ )人(゚∀゚)人( ゚∀)人(∀゚ )人(゚∀゚)人( ゚∀)ノ


上一篇
二十五號坑,來做多個聊天頻道之一(資料建立篇)
下一篇
二十七號坑,來做多個聊天頻道之三(socket事件篇)
系列文
每日挖個坑,用坑填起耍廢聊天室!30

1 則留言

0
King Tzeng
iT邦新手 4 級 ‧ 2019-10-12 18:58:47

今天寫好多喔~(每天都重點誤 (不要打我

我也覺得我hen棒

鼓勵你拍拍手~~~/images/emoticon/emoticon34.gif

我又寫好兩篇囉~(挺胸)
但其實這幾天的扣我幾乎都寫好惹只是在寫文

我要留言

立即登入留言