开始

实现发送信息。
image.png
这里只讲发送文字的。
image.png
拿到时间戳。赋值给time
image.png
判断时间间隔
image.png
参数2是上最后一条信息的时间
image.png

  1. let obj = {
  2. isme: true,
  3. userpic: "../../static/demo/userpic/10.jpg",
  4. type: "img",
  5. data: "../../static/demo/3.jpg",
  6. time: now,
  7. gstime: time.gettime.getChatTime(now,this.list[this.list.length-1].time)
  8. };

把这条数据push进去
image.png

  1. submit(data) {
  2. // console.log(data);
  3. // 构建数据
  4. let now = new Date().getTime();
  5. let obj = {
  6. isme: true,
  7. userpic: "../../static/demo/userpic/10.jpg",
  8. type: "img",
  9. data: "../../static/demo/3.jpg",
  10. time: now,
  11. gstime: time.gettime.getChatTime(now,this.list[this.list.length-1].time)
  12. };
  13. this.list.push(obj);
  14. }

随便发送1条信息
image.png

image.png

image.png

image.png
上下没有显示最新发送的消息。
image.png

如果信息太多的话 就会太卡。外层套一个scroll-view
image.png

  1. <scroll-view scroll-y="true">
  2. </scroll-view>

image.png
表示滚动条的位置。
image.png

  1. scrollTop: 0,

image.png
内容高度
image.png

  1. style:{
  2. contentH:0
  3. },

image.png

  1. :style="{height:style.contentH+'px'}"

image.png

image.png
methods内增加方法initdata()
image.png
拿到当前窗口的高度减去 发消息文本框的高度。
image.png
我们之前定义的是120
image.png
这里获取的高度是px ,所以需要把upx转换为px
image.png

image.png

  1. initdata() {
  2. try {
  3. const res = uni.getSystemInfoSync();
  4. this.style.contentH = res.windowHeight - uni.upx2px(120);
  5. } catch (e) {}
  6. },

页面加载的时候调用。
image.png

  1. onLoad() {
  2. this.getData();
  3. this.initdata();
  4. },

上拉显示最新的消息。
image.png
发送的消息需要滚动 到最下面才能看到消息。
image.png

image.png

发送消息后,滚动条自动滚到最下面。

聊天列表数据的总的和 就是 滚动条最下面的高度。
image.png

加一个id
image.png

  1. id="scrollview"

组件列表组件 最外层的view 要有这个class
image.png

  1. <view class="user-chat-item">

这个方法类似于html里面获取dom的元素。
image.png

image.png
拿到对象实例就可以使用下面的方法 。
image.png
滚动置于底部的方法
image.png
选择器的说明。
image.png
selector返回的是NodeRef对象。、
image.png
执行上面,返回一个回调函数。
image.png
调用方法 必须在onReady里面
image.png

image.png

image.png

image.png
我们用到第二个数组,就是聊天列表的dom元素。
image.png
定义itemH 属性
image.png

拿到每一个聊天列表的高度。

image.png

  1. q.exec((res)=>{
  2. // console.log(JSON.stringify(res));
  3. res[1].forEach((ret)=>{
  4. this.style.contentH += ret.height;
  5. });
  6. });

如果大于可视区域
image.png

image.png

  1. if(this.style.contentH > this.style.contentH) {
  2. this.scrollTop=this.style.contentH;
  3. }

每次提交消息 都要置于底部
image.png
自动到底部
image.png

本节代码

user-chat.vue页面

  1. <template>
  2. <view class="user-chat-item">
  3. <scroll-view id="scrollview" scroll-y="true" :scroll-top="scrollTop" :scroll-with-animation="true"
  4. :style="{height:style.contentH+'px'}">
  5. <!-- 聊天列表 -->
  6. <block v-for="(item,index) in list" :key="index">
  7. <user-chat-list :item="item" :index="index"></user-chat-list>
  8. </block>
  9. <!-- 输入框 -->
  10. <user-chat-bottom @submit="submit"></user-chat-bottom>
  11. </scroll-view>
  12. </view>
  13. </template>
  14. <script>
  15. import userChatBottom from '@/components/user-chat/user-chat-bottom.vue';
  16. import time from '../../common/time.js';
  17. import userChatList from '@/components/user-list/user-chat-list.vue';
  18. export default {
  19. components: {
  20. userChatBottom,
  21. userChatList
  22. },
  23. data() {
  24. return {
  25. scrollTop: 0,
  26. style: {
  27. contentH:0,
  28. itemH:0
  29. },
  30. list: [{
  31. isme: false,
  32. userpic: "../../static/demo/userpic/11.jpg",
  33. type: "text",
  34. data: "哈哈哈",
  35. time: "1555146412"
  36. },
  37. {
  38. isme: true,
  39. userpic: "../../static/demo/userpic/10.jpg",
  40. type: "img",
  41. data: "../../static/demo/3.jpg",
  42. time: "1555146414",
  43. }
  44. ]
  45. }
  46. },
  47. onLoad() {
  48. this.getData();
  49. this.initdata();
  50. },
  51. onReady(){
  52. this.pageToBottom();
  53. },
  54. methods: {
  55. // 初始化参数
  56. initdata() {
  57. try {
  58. const res = uni.getSystemInfoSync();
  59. this.style.contentH = res.windowHeight - uni.upx2px(120);
  60. console.log('contentH:',this.style.contentH);
  61. } catch (e) {}
  62. },
  63. pageToBottom(){
  64. let q=uni.createSelectorQuery();
  65. q.select('#scrollview').boundingClientRect();
  66. q.selectAll('.user-chat-item').boundingClientRect();
  67. q.exec((res)=>{
  68. // console.log(JSON.stringify(res));
  69. res[1].forEach((ret)=>{
  70. this.style.itemH += ret.height;
  71. });
  72. if(this.style.itemH > this.style.contentH) {
  73. console.log('itemH 大于 contentH =>')
  74. this.scrollTop=this.style.itemH;
  75. }
  76. });
  77. },
  78. getData() {
  79. // 从服务器获取到的数据
  80. let arr = [{
  81. isme: false,
  82. userpic: "../../static/demo/userpic/11.jpg",
  83. type: "text",
  84. data: "哈哈哈",
  85. time: "1555146412"
  86. },
  87. {
  88. isme: true,
  89. userpic: "../../static/demo/userpic/10.jpg",
  90. type: "img",
  91. data: "../../static/demo/3.jpg",
  92. time: "1555146414",
  93. },
  94. ];
  95. for (let i = 0; i < arr.length; i++) {
  96. arr[i].gstime = time.gettime.getChatTime(arr[i].time, i > 0 ? arr[i - 1].time : 0);
  97. }
  98. this.list = arr;
  99. },
  100. submit(data) {
  101. // console.log(data);
  102. // 构建数据
  103. let now = new Date().getTime();
  104. let obj = {
  105. isme: true,
  106. userpic: "../../static/demo/userpic/10.jpg",
  107. type: "img",
  108. data: "../../static/demo/3.jpg",
  109. time: now,
  110. gstime: time.gettime.getChatTime(now, this.list[this.list.length - 1].time)
  111. };
  112. this.list.push(obj);
  113. this.pageToBottom();
  114. }
  115. }
  116. }
  117. </script>
  118. <style>
  119. </style>

结束