主页 > 开源代码  > 

记录一下小程序自定义导航栏消息未读已读小红点,以及分组件的消息数量数据实时读取

记录一下小程序自定义导航栏消息未读已读小红点,以及分组件的消息数量数据实时读取

本案例,Message 身为组件,使用不了任何钩子来重新获取 this.getMessageList() 消息列表 使用 props 父子传参,因为 Message 组件使用不了页面生命周期从而无法拿到传递过来的数据 使用 watch 监听不到 props 更不建议使用本地存储,那样和 props 结果差不多

案例中采用的是发送全局事件的形式,在父组件onShow后,因为子组件是父组件的一部分,所以在消息详情中返回子组件后,其实就是在父组件的onShow中调用了 refreshMessageList 方法重新获取子组件 Message 的消息列表 从而实现了实时获取

若不做自定义 tabbar 的话, 没有这么麻烦的去试探数据传输

父组件 Tabbar

<template> <uni-transition mode-class="fade" :duration="200" :show="true"> <view class="main_box"> <index v-if="currentIndex === 0"></index> <myDoctor v-if="currentIndex === 1"></myDoctor> <message v-if="currentIndex === 2"></message> <prescript v-if="currentIndex === 3"></prescript> <my v-if="currentIndex === 4"></my> </view> <view class="foot_box"> <!-- 其实一开始是想把这个作为一个组件来使用的,不过数据传输特麻烦,这时候硬要使用组件化完全不太明智,如果是网页端Vue数据传输绝对简单... --> <!-- <custom-tab-bar ref='tabbar' :currentIndex="currentIndex" @update:currentIndex="updateCurrentIndex"> </custom-tab-bar> --> <uni-transition mode-class="fade" :duration="200" :show="true"> <view> <view class="tab-content"> <slot /> </view> <view class="tabbar"> <view class="navigator"> <view ref='warpper' class="warpper"> <view ref="navItem" class="navigator-item" v-for="(item,index) in tabBar.list" :key="item.pagePath" @click="switchTab(item,index)" :data-index='index'> <img :src="item.iconPath" class="icon" v-if="selectedIndex !== index"> <img :src="item.selectedIconPath" :class="[item.selectIconStyle ? 'icon-select' : 'icon']" v-else> <text :class="['item-text',{'text-active':selectedIndex === index}]">{{item.text}}</text> <view v-if="item.hasUnreadMessage" class="unread-dot"></view> </view> </view> </view> </view> </view> </uni-transition> </view> </uni-transition> </template> <script> import { FILE_URL } from '../../api/base_api.js'; import { GET_MESSAGE } from '../../api/user.js'; import { store } from '../../store/modules/index.js' var Hub = require('../../utils/signalR.js') import index from '@/pages/index/index.vue' import myDoctor from '@/pages/my-doctor/my-doctor.vue' import message from '@/pages/message/message.vue' import prescript from '@/pages/prescript/prescript.vue' import my from '@/pages/person/person.vue' export default { components: { index, my, message, prescript, myDoctor }, data() { return { // 定义一个目前的 unRead 状态,若是集合起来大于 0,那么就作为标记 unRead 数量,针对系统聊天 presentReadState: 0, messageList: [], pageIndex: 1, pageSize: 10, currentIndex: uni.getStorageSync('selectedIndex') || 0, selectedIndex: uni.getStorageSync('selectedIndex') || 0, // 标记 tabBar: { list: [{ pagePath: "pages/index/index", text: "首页", iconPath: "../../static/images/tabbar/home.png", selectedIconPath: "../../static/images/tabbar/home1.png" }, { pagePath: "pages/my-doctor/my-doctor", text: "我的医生", iconPath: "../../static/images/tabbar/doctor.png", selectedIconPath: "../../static/images/tabbar/doctor1.png" }, { pagePath: "pages/message/message", text: "消息", iconPath: "../../static/images/tabbar/message.png", selectedIconPath: "../../static/images/tabbar/message1.png", hasUnreadMessage: uni.getStorageSync("inline-msg") // 记录 未读 | 已读 }, { pagePath: "pages/prescript/prescript", text: "药膳商城", iconPath: "../../static/images/tabbar/mingyao2.png", selectedIconPath: "../../static/images/tabbar/mingyao3.png", selectIconStyle: true }, { pagePath: "pages/person/person", text: "我的", iconPath: "../../static/images/tabbar/my2=.png", selectedIconPath: "../../static/images/tabbar/my1.png" } ] }, } }, methods: { loadsocket() { var _this = this; if (_this.timeout) clearTimeout(_this.timeout); _this.hubConnect = new Hub.HubConnection(); _this.hubConnect.token = uni.getStorageSync('WX_TOKEN') _this.hubConnect.start(FILE_URL + "/api/chathub"); _this.hubConnect.onOpen = res => {} _this.hubConnect.on("Receive", function(res) { console.log("有数据了", res); uni.setStorageSync("inline-msg", true) }) _this.hubConnect.on("UsingCode", res => {}) _this.hubConnect.on("UsedCode", res => {}) }, switchTab(item, index) { this.currentIndex = index; this.tabBar.list.forEach((v, i) => { if (item.pagePath === v.pagePath) { uni.setStorageSync('selectedIndex', index); } }) this.selectedIndex = uni.getStorageSync('selectedIndex') }, }, onShow() { this.tabBar.list[2].hasUnreadMessage = uni.getStorageSync("inline-msg") // 父子传参方法也不好用,message组件中没有onShow方法,而且watch监听不到props // message为组件,其他方法不太好用,使用事件总线发送全局事件 refreshMessageList uni.$emit('refreshMessageList'); }, mounted() { this.loadsocket() }, } </script>

其中一个子组件 Message

<template> <view class="message"> <!-- 页面头 --> <view class="header"> <image src="../../static/images/index/index-topbar-back.png" mode="" class="back-img"></image> <view class="top-bar"> <view class="name">消息</view> </view> </view> <!-- 没有消息 --> <view class="none" style="padding-top: 200rpx;" v-if="!messageList.length"> <u-empty mode='list' text='暂无消息'></u-empty> </view> <!-- 消息列表 --> <view class="list" v-else> <view class="item" v-for="(item,index) in messageList" :key="index" @click="handleToChat(item)"> <view class="avatar"> <image :src="item.groupImage" mode=""></image> </view> <view class="msg-info"> <view class="left"> <view class="name">{{item.groupName}}</view> <view class="msg">{{item.lastMessage}}</view> </view> <view class="right"> <view class="date">{{item.changeTime.slice(5,16)}}</view> <view class="no-read-count" v-if="item.unRead">{{item.unRead}}</view> </view> </view> </view> </view> <!-- <custom-tab-bar ref='tabbar'></custom-tab-bar> --> <!-- 登录弹窗 --> <!-- <u-popup v-model="isShowLogin" mode="center" border-radius="14" :closeable='true'> <AuthLogin @setData='getLoginData'></AuthLogin> </u-popup> --> </view> </template> <script> import { APP_BASE_URL, FILE_URL } from '../../api/base_api.js'; import { GET_MESSAGE } from '../../api/user.js'; // import AuthLogin from '../common/auth-login.vue' var Hub = require('../../utils/signalR.js') export default { data() { return { messageList: [], pageIndex: 1, pageSize: 10, // isShowLogin: false, //登录弹窗 } }, watch: { presentReadState(newValue, oldValue) { } }, components: { // AuthLogin }, onHide() { console.log('断开') this.hubConnect.close(); }, mounted() { if (uni.getStorageSync('WX_TOKEN')) { this.messageList = [] this.getMessageList() // 当回到 message 组件中(其实就是在父组件的onShow中),调用全局事件refreshMessageList,来重置消息列表 uni.$on('refreshMessageList', this.getMessageList); } if (this.hubConnect) { if (this.hubConnect.connection == null || !this.hubConnect.openStatus) { this.loadsocket(); } } else { this.loadsocket(); } }, beforeDestroy() { // 销毁 uni.$off('refreshMessageList', this.getMessageList); }, methods: { // 获取弹窗传值 // getLoginData(status) { // this.isShowLogin = status // }, // 获取消息列表 getMessageList() { GET_MESSAGE({ page: this.pageIndex, limit: this.pageSize }).then(res => { if (res.data) { this.messageList = res.data } }) }, // 获取 getcode() { if (this.hubConnect && this.hubConnect.connection != null && this.hubConnect.openStatus) { this.hubConnect.send("GetCode", 3); this.xunhuan(); } }, // 链接 loadsocket() { var _this = this; if (_this.timeout) clearTimeout(_this.timeout); // connection _this.hubConnect = new Hub.HubConnection(); _this.hubConnect.token = uni.getStorageSync('WX_TOKEN') _this.hubConnect.start(FILE_URL + "/api/chathub"); _this.hubConnect.onOpen = res => { } _this.hubConnect.on("Receive", res => { uni.setStorageSync("inline-msg", true) _this.messageList = [] _this.getMessageList() }) _this.hubConnect.on("UsingCode", res => { _this.show = true; }) _this.hubConnect.on("UsedCode", res => { }) }, // 跳转聊天 handleToChat(item) { if (!uni.getStorageSync('WX_TOKEN')) { // this.isShowLogin = true return false } uni.navigateTo({ url: '/pages/tools/chat/sys-message?item=' + JSON.stringify(item) }) } }, } </script>
标签:

记录一下小程序自定义导航栏消息未读已读小红点,以及分组件的消息数量数据实时读取由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“记录一下小程序自定义导航栏消息未读已读小红点,以及分组件的消息数量数据实时读取