vue,一路走来(9)--聊天窗口
闲暇时间,介绍一下我做一个聊天窗口的心得。如图:
首先要考虑的是得判断出是自己的信息还是对方发来的信息,给出如图的布局,切换不同的类。
<li class="clearfix" v-for="(talk,index) in talks" v-bind:class="{'even':othername!=talk.send_from_id,'odd':othername==talk.send_from_id}"> <span v-show="showTime(index)" :id="index">{{getLocalTime(talk.message_time)}}</span> <img v-bind:src="getUserimg" alt="" v-if="othername!=talk.send_from_id"> <img v-bind:src="meUserimg" alt="" v-else> <b></b> <div> <p>{{talk.content}}</p> </div> </li>
/*even 偶 odd 奇*/
.content-talk ul li.odd img{width:45px;height:45px;border-radius: 50%;float: left;background: url(../assets/peoper.png) no-repeat center center;background-size: 45px 45px;} .content-talk ul li.even img{width:45px;height:45px;border-radius: 50%;float: right;background: url(../assets/peoper.png) no-repeat center center;background-size: 45px 45px;} .content-talk ul li.odd .in_talk p{background: #fff;float:left;margin-left: 10px;max-width:60%;font-size: 14px;padding:10px;border-radius: 6px;} .content-talk ul li.odd b{width:8px;height:14px;display: inline-block;background: url(../images/left.jpg) no-repeat;background-size: 8px 14px;position: absolute;left:58px;top:8px;} .content-talk ul li.even .in_talk p{background: #f6fff6;float:right;margin-right: 10px;max-width:60%;border-radius: 6px;font-size: 14px;padding:10px; } .content-talk ul li.even b{width:8px;height:14px;display: inline-block;background: url(../images/right.jpg) no-repeat;background-size: 8px 14px;position: absolute;right:58px;top:8px;}
或许你会看得一脸懵,根据接口拿到的信息,othername就是当前与你聊天的这个人,如果与send_from_id一致那么就是对方的信息,反之是你自己发的信息。
接下来就是输入框了,定位在底部,因为没有发送按钮,所以必须触发键盘和手机的Enter键,还有一个问题是,在我手机Enter键显示的是'换行'字眼。
以下是解决办法,加了form标签,但必须关掉action的功能。“换行”就变成“前往”
<form action="" onkeydown="if(event.keyCode==13)return false;"> <mt-field type="text" v-model="content" @keyup.native="send($event)"></mt-field>
</form>
//发送消息 send(ev){ if(ev.keyCode==13){
var sendtoid=this.userid; // console.log(sendtoid) var sendfromid=""; var subject=""; var replyid=0; if(this.content!=''){ this.$http.post(this._getUrl()+"User/send", {"sendfromid":sendfromid,"sendtoid":sendtoid,"subject":subject,"content":this.content,"replyid":replyid},{emulateJSON:true} ).then((response) => { response = response.body; if(response.error_code==200){ Toast({ message: '发送成功' }); this.getread(); //重新获取数据
this.content='' } else{ Toast({ message: response.error_msg }); } }); }else{ Toast({ message: '不能为空' }); } } },
接下来我用到了Mint-ui的Loadmore 顶部下拉刷新加载更多消息
http://mint-ui.github.io/docs/#/zh-cn2/loadmore
接口数据,如图:
在 loadTop()函数加载更多中,不能再用push()。
如下这3张图可能形象一点,created(),获取到第一页数据
第一页数据:
第二页数据:
首先得让第二页最底下的数据先添加进来,用了for循环 for(let j = sayLists.length-1; j >-1; j--) 数组序号index从0开始,
然后数据就需要使用unshift() 方法向数组的开头添加元素,于是用了下面方法:
//加载更多 loadTop() { // var userid=this.$route.params.userid; let page = (Math.ceil(this.talks.length/this.pagesize))+ 1; // console.log(page) this.$http.get(this._getUrl()+"User/readAll/userid/" + this.userid +"/pagesize/"+this.pagesize+"/page/" + page).then((response) => { let say_code =response.body.error_code; let sayLists = response.body.list; if(say_code=='200'){ for (let j = sayLists.length-1; j >-1; j--) {
// console.log(sayLists[j]) this.talks.unshift(sayLists[j]); this.contentlogin=true; } }else{ this.allLoaded = true; this.$refs.loadmore.onTopLoaded(); this.contentlogin=false; } }); },
最后的问题是,页面进来显示最新聊天,在body底部。
//显示最底部信息 bottomshow(){ let count=0; let interval=setInterval(() =>{ if(count>200){ clearInterval(interval); } count++; if(document.body.scrollTop != document.body.scrollHeight){ document.body.scrollTop = document.body.scrollHeight; // console.log(document.body.scrollTop) } if(document.body.scrollTop == document.body.scrollHeight){ clearInterval(interval); } },0); }
加上定时器,是因为页面一进来未能获取到盒子高度并发生滚动,所以加了定时器,利用count++,延迟点。