美文网首页
vue 纯js实现下拉加载,适用于聊天记录场景

vue 纯js实现下拉加载,适用于聊天记录场景

作者: 八妹sss | 来源:发表于2021-04-12 15:53 被阅读0次
<div class="msg-wrapper"
        ref="scrollDiv">
        <ul v-if="msgList.length" class="msg-list">
          <li
            :class="msgInfo.mp ? 'msg-item-right' : 'msg-item-left'"
            v-for="(msgInfo, i) in msgList"
            :key="i">
            <div class="avatar-name">
              <div class="avatar">
                <img :src="msgInfo.avatar" alt="">
              </div>
              <div class="name">{{msgInfo.nickName}}</div>
            </div>
            <div class="msg-box">
              <div class="msg-info">
                <!-- 文本消息 -->
                <div class="msg-text"
                  v-if="msgInfo.msgType === 'text'">
                  <div class="msg-cont"
                    v-html="handleTextCont(msgInfo)"></div>
                </div>
                <!-- 链接消息 -->
                <div class="msg-text"
                  v-if="msgInfo.msgType === 'link'">
                  <div class="msg-cont">{{`【${msgInfo.msgTypeInfo}】${msgInfo.url}`}}</div>
                </div>
                <!-- 图片 -->
                <div class="msg-other"
                  v-if="msgInfo.msgType === 'image'">
                  <div class="msg-cont">
                    <template v-if="(msgInfo.media && msgInfo.media.otherMedias && msgInfo.media.otherMedias.length)">
                      <!-- 图片之群发消息 -->
                      <div class="bg"
                        @click="handlePreviewImg(msgInfo.media.otherMedias[0])"
                        :style="{backgroundImage: `url(${msgInfo.media.otherMedias[0] && getWxImg(msgInfo.media.otherMedias[0].mediaUrl)})`}"></div>
                    </template>
                    <template v-else>
                      <!-- 图片之粉丝发送 -->
                      <div class="bg"
                        @click="handlePreviewImg(msgInfo)"
                        :style="{backgroundImage: `url(${getWxImg(msgInfo.picUrl)})`}"></div>
                    </template>
                  </div>
                </div>
                <!-- 视频、小视频-->
                <div class="msg-other"
                  v-if="msgInfo.msgType === 'video' || msgInfo.msgType === 'small_video'">
                  <div class="msg-cont">
                    <!-- 视频之群发消息 -->
                    <template v-if="msgInfo.media && msgInfo.media.otherMedias && msgInfo.media.otherMedias.length">
                      <div class="bg"
                        @click="handlePreviewVideo(msgInfo.media.otherMedias[0])"
                        :style="{backgroundImage: `url(${msgInfo.media.otherMedias[0] && getWxImg(msgInfo.media.otherMedias[0].picUrl)})`}">
                        <div class="mask"></div>
                      </div>
                    </template>
                    <template v-else>
                      <!-- 视频之粉丝发送 -->
                      <div class="bg"
                        @click="handlePreviewVideo(msgInfo)"
                        :style="{backgroundImage: `url(${getWxImg(msgInfo.thumbUrl)})`}">
                        <div class="mask"></div>
                      </div>
                    </template>
                  </div>
                </div>
                <!-- 图文 -->
                <div class="msg-other"
                  v-if="msgInfo.msgType === 'news'">
                  <div class="msg-cont">
                    <div class="bg"
                      :style="{backgroundImage: `url(${msgInfo.media.newsMedia && getWxImg(msgInfo.media.newsMedia.thumbUrl)})`}">
                    </div>
                    <div class="title">{{msgInfo.media.newsMedia && msgInfo.media.newsMedia.title}}</div>
                  </div>
                </div>
                <!-- 音频 -->
                <div class="msg-other"
                  v-if="msgInfo.msgType === 'voice'">
                  <div class="msg-cont">
                    <!-- 语音之消息群发 -->
                    <template
                      v-if="msgInfo.media && msgInfo.media.otherMedias && msgInfo.media.otherMedias.length">
                      <voicePlayer
                        :voiceUrl="msgInfo.media.otherMedias[0] && msgInfo.media.otherMedias[0].mediaUrl"
                        :direction="msgInfo.mp ? 'rtl': 'ltr'"
                        :bgColor="msgInfo.mp ? '#fff': '#96EC69'"
                        :progressColor="msgInfo.mp ? '#f2f2f2': '#6fdb36'"/>
                    </template>
                    <template v-else>
                      <!-- 语音之粉丝发送 -->
                      <voicePlayer
                        :voiceUrl="msgInfo.url"
                        :direction="msgInfo.mp ? 'rtl': 'ltr'"
                        :bgColor="msgInfo.mp ? '#fff': '#96EC69'"
                        :progressColor="msgInfo.mp ? '#f2f2f2': '#6fdb36'"/>
                    </template>
                    <!-- <div class="cont-audio"></div> -->
                  </div>
                </div>
                <!-- 关注、取消关注、通过二维码关注 -->
                <div class="msg-text"
                  v-if="msgInfo.msgType === 'subscribe' || msgInfo.msgType === 'unsubscribe' || msgInfo.msgType === 'subscribe_by_qrcode'">
                  <div class="msg-cont">{{`【${msgInfo.msgTypeInfo}】`}}</div>
                </div>
                <!-- 扫描二维码 -->
                <div class="msg-text"
                  v-if="msgInfo.msgType === 'scan'">
                  <div class="msg-cont">{{`【${msgInfo.msgTypeInfo}】`}}</div>
                </div>
                <!-- 点击自定义菜单、点击菜单跳转 -->
                <div class="msg-text"
                  v-if="msgInfo.msgType === 'click' || msgInfo.msgType === 'view'">
                  <div class="msg-cont"
                    v-html="handleMenuCont(msgInfo)"></div>
                </div>
                <!-- 定位 -->
                <div class="msg-other"
                  v-if="msgInfo.msgType === 'location'">
                  <div class="msg-cont">
                    <div class="icon-location"></div>
                    <div class="address">
                      <p class="area">{{msgInfo.title}}</p>
                      <!-- <p class="detail">上海市徐汇区肇嘉浜路807号</p> -->
                    </div>
                  </div>
                </div>
              </div>
              <div class="creat-time">{{msgInfo.createTime}}</div>
            </div>
          </li>
        </ul>
        <div v-else class="default-page">暂无数据</div>
      </div>
export default {
  data () {
    return {
      loadingList: false, // 列表加载时的loading
      date: '',
      timeValue: [],
      pickerOptions: {
        disabledDate (time) {
          // 今天及以前
          return time.getTime() > Date.now()
        }
      },
      page: 1,
      pageSize: 10,
      count: 0,
      scrollHeight: 0,
      msgList: []
    }
  },
  methods: {
    // 时间筛选
    handleSearch () {
      this.page = 1
      this.msgList = []
      this.scrollHeight = 0
      this.fetchMsgList()
    },
    // 获取消息列表
    fetchMsgList () {
      if (this.loadingList) {
        return
      }
      this.loadingList = true
      this.scrollHeight = this.$refs.scrollDiv ? this.$refs.scrollDiv.scrollHeight : 0
      let startT = this.timeValue.length ? this.timeValue[0] : null
      let endT = this.timeValue.length ? this.timeValue[1] : null
      let startTime = startT ? this.formatDatePattern(new Date(startT), 'yyyyMMddhhmmss') : null
      let endTime = endT ? this.formatDatePattern(new Date(endT), 'yyyyMMddhhmmss') : null
      let appid = sessionStorage.getItem('appid')
      let url = `${this.SERVICE_WECHAT}/msg/${appid}/msg/browse/list`
      this.get(url, {
        startTime: startTime,
        endTime: endTime,
        currentPage: this.page,
        pageSize: this.pageSize
      }).then(res => {
        this.loadingList = false
        if (res.data.code === 200) {
          let data = res.data.data
          if (data && data.msgList) {
            this.count = +data.msgList.total
            if (data.msgList.list && data.msgList.list.length) {
              let msgList = data.msgList.list.reverse()
              this.msgList = msgList.concat(this.msgList)
            }
          }
          if (this.page === 1) {
            // 首次渲染后获取scrollHeight并滑动到底部。
            setTimeout(() => {
              let currScrollHeight = this.$refs.scrollDiv.scrollHeight
              this.$refs.scrollDiv.scrollTo(0, currScrollHeight)
            }, 20)
          } else {
            // 滚动到加载前的位置
            setTimeout(() => {
              let currScrollHeight = this.$refs.scrollDiv.scrollHeight
              this.$refs.scrollDiv.scrollTo(0, currScrollHeight - this.scrollHeight)
            }, 20)
          }
        }
      }).catch(e => {
        this.loadingList = false
        this.handleError(e)
      })
    },
    dateChange () {
      this.timeValue = this.timeRange
    },
    // --------------无限加载----------------
    handleScroll (e) {
      // 加定时器进行节流
      setTimeout(() => {
        if (e.target.scrollTop === 0 && this.count > this.msgList.length && !this.loadingList) {
          // 将scrollTop置为10以便下次滑到顶部
          e.target.scrollTop = 10
          // 加载数据
          this.page += 1
          this.fetchMsgList()
        }
      }, 500)
    }
  },
  created () {
    this.date = this.dateDefault
    this.timeValue = this.timeRange
    this.fetchMsgList()
  },
  mounted () {
    this.$refs.scrollDiv.addEventListener('scroll', this.handleScroll, true)
  },
  beforeDestroy () {
    this.$refs.scrollDiv.removeEventListener('scroll', this.handleScroll)
  }
}

相关文章

网友评论

      本文标题:vue 纯js实现下拉加载,适用于聊天记录场景

      本文链接:https://www.haomeiwen.com/subject/rsdekltx.html