最近自己在做一个包含聊天功能的项目,其中用到的Vue+webscocket,遇到了好多问题,包括自己遇到的一些需求。
需求:
- 断线自动连接
- 判断主动退出和被动掉线
- 聊天框消息不因添加而向下滚动
解决方法:
- 断线在监听里面,然后关闭当前webSocket进程后再去请求创建新的ws进程;
this.socket.onclose = function(e){
let logout = CHAT.logout()//退出聊天
let admin_logout = ADMIN_CHAT.logout()//admin聊天退出
console.log('主聊天断开')
if(logout && admin_logout){//判断
setTimeout(()=>{
let reloadWS = store.state.reloadWS?store.state.reloadWS+1:1
store.commit('merge',{
reloadWS:reloadWS,
})
},1000)
}
}
2 第一种情况:主动退出,调用logout
logout:function(){
this.socket.close()
this.socket.onclose = function(e){
console.log('用户主动退出!')
}
return true
}
第二种情况:被动掉线,断线自动连接,见1。
3.聊天界面的消息是不断添加的,但是如果用户想查看上面的记录时,不做处理的话会被新消息强制拖到底部。为解决这种情况添加聊天界面滚动条判断。
最主要的问题还是解决vue 在push数据时动态加载导致滚轮滚动到底的问题。
我尝试过了splice(start,deleteCount,val1,val2,…),但是还是会触发,之后我用了concat(返回一个新数组,是将参数添加到原数组中构成的 ),没有触发滚动条,而且消息也添加了进去。
查了下vue官方文档,里面介绍的vue关于数组更新检测的触发机制,如下
变异方法
Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下:
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
替换数组
变异方法 (mutation method),顾名思义,会改变被这些方法调用的原始数组。相比之下,也有非变异 (non-mutating method) 方法,例如:filter(), concat() 和 slice() 。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组:
CHAT.msgArr = CHAT.msgArr.concat(data)
你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的、启发式的方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。