Vue開(kāi)發(fā)聊天界面

2021-9-1    前端達(dá)人

Vue開(kāi)發(fā)聊天界面(一)

最近業(yè)務(wù)里面有個(gè)需求就是開(kāi)發(fā)一個(gè)類(lèi)似微信的聊天頁(yè)面的H5,不需要像微信那么復(fù)雜,但是得有個(gè)樣子,弄了半天之后終于有了個(gè)樣子。決定寫(xiě)個(gè)博客記一下這個(gè)過(guò)程,希望后續(xù)不會(huì)鴿

組件拆分

拆了3個(gè),打字的,聊天item,聊天list。大概就這樣了

其中聊天list 用了一個(gè)better-scroll這個(gè)第三方插件。

首先第一步就是開(kāi)發(fā)這個(gè)聊天item

聊天item 開(kāi)發(fā)

分析一下需求,別人發(fā)過(guò)來(lái)的和我們發(fā)過(guò)去的是兩個(gè)排版和樣式,但是不用單獨(dú)寫(xiě)兩個(gè),用個(gè)邏輯區(qū)分一下就可以了,也可以動(dòng)態(tài)綁定css什么的差別很小。

<template> <div class="record-wrapper"> <!-- 時(shí)間,后續(xù)開(kāi)發(fā) --> <div class="time"></div> <!-- 消息, msg通用樣式 msg-right/msg-left 區(qū)分排版左右 --> <div v-if="from == 1" class="msg msg-right"> <div class="img-wrapper"> <img class="img" :src="from1" /> </div> <!-- 消息框, msg通用樣式 message-wrapper-right/left 區(qū)分聊天框顏色 --> <div class="message-wrapper message-wrapper-right"> <div class="message">{{ message }}</div> </div> </div> </div> </template> 

這個(gè)是只有1邊的,邏輯就是在消息那邊加個(gè)v-if,判斷來(lái)源,也可以動(dòng)態(tài)綁定css

弄好以后就這樣

<template> <div class="record-wrapper"> <div class="time"></div> <div v-if="from == 1" class="msg msg-right"> <div class="img-wrapper"> <img class="img" :src="from1" /> </div> <div class="message-wrapper message-wrapper-right"> <div class="message">{{ message }}</div> </div> </div> <div v-else class="msg msg-left"> <div class="img-wrapper"> <img class="img" :src="from2" /> </div> <div class="message-wrapper message-wrapper-left"> <div class="message">{{ message }}</div> </div> </div> </div> </template> <script> export default {
  name: "",
  props: {
    from: Number, // 1: 自己    2: 別人
    message: String,
    timestamp: Date,
  },
  data() {
    return {
      from1: require("../../../assets/imgs/from1.jpg"),
      from2: require("../../../assets/imgs/from2.jpg"),
    };
  },
}; </script> 

個(gè)人覺(jué)得css還是比較重要的,這里用了sass來(lái)寫(xiě)。主要解決方案就是用一個(gè)display:flex配合上flex-direction: row-reverse讓頭像和消息左右排列

<style lang="scss" scoped> .record-wrapper { margin: 4px; padding: 4px; } .time { text-align: center; } .msg { display: flex; flex-direction: row; .message-wrapper { max-width: 220px; margin: 0px 10px 0px 10px; .message { margin: 8px; word-wrap: break-word; //英文換行 } } .message-wrapper-left { background-color: lightslategray; border-radius: 0px 12px 12px 12px; } .message-wrapper-right { background-color: powderblue; border-radius: 12px 0px 12px 12px; } .img { flex: auto; height: 36px; width: 36px; border-radius: 8px; } } .msg-right { flex-direction: row-reverse; } .msg-left { flex-direction: row; } </style> 

這個(gè)是沒(méi)有調(diào)樣式的,只是為了自己嗨弄的,可能會(huì)很丑。
最后大概就是這樣的

Vue開(kāi)發(fā)聊天界面(二)

我開(kāi)發(fā)好了一個(gè)聊天的item,可以根據(jù)發(fā)送方和接收方來(lái)分別渲染一個(gè)item,這一章我把他們放在一個(gè)list的界面里面,讓一串item構(gòu)成一個(gè)聊天頁(yè)面,并且這個(gè)聊天頁(yè)面能夠上下滾動(dòng)。

其實(shí)我覺(jué)得很簡(jiǎn)單,難點(diǎn)就2個(gè)。首先是滑動(dòng),這里用了better-scroll這個(gè)組件,可以在網(wǎng)上搜,挺好用的。另一個(gè)就是頁(yè)面布局的問(wèn)題,寫(xiě)點(diǎn)css還是沒(méi)得問(wèn)題的。
首先去better-scroll的官網(wǎng),按著他的核心邏輯抄一下。不詳細(xì)談了,總之來(lái)說(shuō),會(huì)有三層嵌套。我個(gè)人命名他們?yōu)? wrapper 和content和 item 這三層。
先弄一個(gè)json,當(dāng)做會(huì)被填充的數(shù)據(jù)。

export const chatItems = [ { type:1, message:"fdaf地方撒風(fēng)大撒風(fēng)阿斯頓飛fd阿斯頓飛安德森發(fā)大水發(fā)大水發(fā)大水奮斗發(fā)的大撒風(fēng)安德森 發(fā)大發(fā)大水發(fā)", from:1, timestamp: new Date() }, { type:1, message:"fdaf地方撒風(fēng)大撒aa風(fēng)阿斯頓飛ffdsafsfadsfadsfjlkjsadflkosdajfl asdjlffsaf水奮斗發(fā)的大撒風(fēng)安德森 發(fā)大發(fā)大水發(fā)", from:1, timestamp: new Date() }, { type:1, message:"做緊d咩嘢?", from:2, timestamp: new Date() }, { type:1, message:"???", from:2, timestamp: new Date() }, ] 

然后開(kāi)始寫(xiě)vue的代碼

<template> <div class="scroll-wrapper" ref="scroll"> <div class="scroll-content"> <chat-item v-for="item in chatItems" :key="item.message" :type="item.type" :message="item.message" :timestamp="item.timestamp" :from="item.from" ></chat-item> </div> </div> </template> <script> import BScroll from "@better-scroll/core";
import MouseWheel from "@better-scroll/mouse-wheel"
import ChatItem from "./ChatItem";
import { chatItems } from "../../../assets/data/items";

BScroll.use(MouseWheel)

export default {
  name: "",
  data() {
    return {
      chatItems,
      bs: null
    };
  },
  components: {
    "chat-item": ChatItem,
  },

  mounted() {
    this.init();
  },
  beforeDestroy() {
    this.bs.destroy();
  },
  methods: {
    // better-scroll的代碼
    init() {
      this.bs = new BScroll(this.$refs.scroll, {
        scrollY: true, // 上下滾動(dòng)
        click: true,   // 開(kāi)啟點(diǎn)擊事件
        startY: document.querySelector(".scroll-wrapper").clientHeight - this.$refs.scroll.scrollHeight + 5 , // 初始高度
        mouseWheel: true,   // 鼠標(biāo)滾動(dòng)
        probeType: 2, // listening scroll hook
      });

      // 下面的不要也行,官網(wǎng)抄的順便留下來(lái)了
      this.bs.on("scroll", ({ y }) => {
        console.log("scrolling:" + y);
      });
      this.bs.on("scrollEnd", () => {
        console.log("scrollingEnd");
      });
    },
    clickHandler(item) {
      alert(item);
    },
  },
}; </script> <style lang="scss" scoped> .scroll-wrapper {
  height: calc(100% - 160px);  // 留一些空間給 打字的地方 和 header
  overflow: hidden;    // 非常之關(guān)鍵
} </style> 

最后是這個(gè)樣子的了

藍(lán)藍(lán)設(shè)計(jì)建立了UI設(shè)計(jì)分享群,每天會(huì)分享國(guó)內(nèi)外的一些優(yōu)秀設(shè)計(jì),如果有興趣的話,可以進(jìn)入一起成長(zhǎng)學(xué)習(xí),請(qǐng)掃碼ben_lanlan,報(bào)下信息,會(huì)請(qǐng)您入群。歡迎您加入噢~~希望得到建議咨詢、商務(wù)合作,也請(qǐng)與我們聯(lián)系。

文章來(lái)源:簡(jiǎn)書(shū)。作者:Good_Nine9

分享此文一切功德,皆悉回向給文章原作者及眾讀者.
免責(zé)聲明:藍(lán)藍(lán)設(shè)計(jì)尊重原作者,文章的版權(quán)歸原作者。如涉及版權(quán)問(wèn)題,請(qǐng)及時(shí)與我們?nèi)〉寐?lián)系,我們立即更正或刪除。

藍(lán)藍(lán)設(shè)計(jì)bouu.cn )是一家專(zhuān)注而深入的界面設(shè)計(jì)公司,為期望卓越的國(guó)內(nèi)外企業(yè)提供卓越的UI界面設(shè)計(jì)、BS界面設(shè)計(jì) 、 cs界面設(shè)計(jì) 、 ipad界面設(shè)計(jì) 、 包裝設(shè)計(jì) 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計(jì)、 網(wǎng)站建設(shè) 、平面設(shè)計(jì)服務(wù)





分享本文至:

日歷

鏈接

個(gè)人資料

存檔