前言

Node+WebSocket+Vue聊天室: 界面美化,代码优化 - 第六章

感谢你再次点开了我,只能说明你是喜欢我的,对不对?哈哈,开个玩笑。

今天主要是把之前的聊天室界面美化一下,不至于太难看,同时也对代码做了一些优化。具体细节请看详细内容。

并且可以线上体验了:体验地址

如果您还没有看过之前的文字,请点击下方链接查看!
推荐文章:

《Nodejs + WebSocket简单介绍及示例 - 第一章》
《Nodejs + WebSocket + Vue 实现多人聊天室WebIM功能 - 第二章》
《Nodejs + WebSocket + Vue 一对一、一对多聊天室 - 第三章》
《Node + WebSocket + Vue 一对一、一对多聊天室消息已读未读 - 第四章》
《Node + WebSocket + Vue 聊天室创建群聊/加入群聊功能 - 第五章》

客户端HTML代码优化

Node+WebSocket+Vue聊天室: 界面美化,代码优化 - 第六章

页面先分为左右布局,然后左/右里面再分为上中下布局。

很自然,我们想到了flex布局,Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。

... <div class="web-im"> <div class="left"> <div class="aside content"> <div class="header"> ... </div> <div class="body user-list"> ... </div> <div class="footer"> ... </div> </div> </div> <div class="right content"> <div class="header">...</div> <div class="body im-record" id="im-record"> ... </div> <div class="footer im-input"> ... </div> </div> </div> ...

css样式是用stylus书写的,有些初学的小伙伴应该有点点不是很明白,但是大致能懂,就是把嵌套的书写,使其看起来更容易阅读、维护。

如果对flex、和stylus不是很明白的小伙伴,可以留言区留言,后期看情况出更详细的教程,这里就不啰嗦了。

.web-im
  display flex
.left
  width 220px
.right
    flex 1
.content
  display: flex;
  flex-direction: row;
  flex: 1;
  box-sizing: border-box;
  min-width: 0;
  flex-direction: column;
  .header
    box-shadow 1px -1px 2px 2px #eee
    line-height 40px
    height 40px
    font-size 24px
    z-index 10
    background #fff
  .body
    flex 1
    overflow-y auto
    box-shadow 1px 1px 1px #eee
  .footer
    box-shadow 1px 1px 8px #eee
    height 60px

WebSocket客户端JS

我们主要研究变的地方,没有变的通过…表示。同时,如果您想看完整代码,可以去文章最下方“了解更多”,来获取源码查看。

... export default { ... mounted() { ... // 监听页面刷新,关闭事件,退出聊天室 window.onbeforeunload = function (e) { vm.socket.send(JSON.stringify({ uid: vm.uid, type: 2, nickname: vm.nickname, bridge: [] })); } }, computed: { // 当前展示的消息列表 currentMessage() { let vm = this; let data = vm.messageList.filter(item=>{ if(item.type === 1) { return item; } else if(this.groupId) { return item.groupId === this.groupId } else if(item.bridge.length){ return item.bridge.sort().join(',') == vm.bridge.sort().join(',') } }) data.map(item=>{ item.status = 0 return item; }) return data; }, // 当前群组列表 currentGroups() { let vm = this; vm.groups.map(group=>{ // 找出群组对应未读消息 group.unread = this.messageList.filter(item=>{ return item.groupId === group.id && item.status === 1 }).length return group; }) return vm.groups; }, // 群组列表是否有未读消息 groupsUnRead(){ return this.messageList.some(item=>{ return item.groupId && item.status === 1 }) }, // 联系人列表是否有未读消息 usersUnRead(){ return this.messageList.some(item=>{ return item.bridge.length && item.status === 1 }) }, // 当前联系人列表 currentUserList() { let vm = this; vm.users.map(user=>{ // 找出联系人对应未读消息 user.unread = this.messageList.filter(item=>{ return item.bridge.length && item.uid === user.uid && item.status === 1 }).length return user; }) return vm.users; } }, methods: { ... conWebSocket(){ let vm = this; if(window.WebSocket){ ... socket.onmessage = function(e){ ... // 消息列表滚动条始终在最底部 vm.$nextTick(function(){ var div = document.getElementById('im-record'); div.scrollTop = div.scrollHeight; }) } } } ... } }

这次代码优化,主要是在计算属性上面做了大的调整。之前都是用方法来获取未读已读等,现在直接计算属性先一步计算,然后渲染到页面。

WebSocket服务端

... // 注销 case 2: delete conns[''+obj.uid+'']; users.map((item, index)=>{ if(item.uid === obj.uid){ item.status = 0; } return item; }) boardcast({ type: 1, date: moment().format('YYYY-MM-DD HH:mm:ss'), msg: obj.nickname+'退出了聊天室', users: users, groups: groups, uid: obj.uid, nickname: obj.nickname, bridge: [] }); break; ...

服务端主要增加了一个注销功能,用户下线。
同时,之前type=2是发送消息,现在改成了100是发送消息,2是用户下线。

快速预览效果

Node+WebSocket+Vue聊天室: 界面美化,代码优化 - 第六章

Node+WebSocket+Vue聊天室: 界面美化,代码优化 - 第六章

源码地址:源码地址
体验地址:体验地址