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

这篇具有很好参考价值的文章主要介绍了记录一下小程序自定义导航栏消息未读已读小红点,以及分组件的消息数量数据实时读取。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本案例,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 && presentReadState" class="unread-dot">
										{{presentReadState < 99 ? presentReadState : ''}}
									</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';
	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')
			},
			// 因为 message 为组件  onShow 不可使用,所以这里想使用父子传参的方式解决消息页的未读消息处理
			// 此处更改为记录未读数量
			getMessageList() {
				GET_MESSAGE({
					page: this.pageIndex,
					limit: this.pageSize
				}).then(res => {
					if (res.data) {
						this.messageList = res.data
						let readNumberList = this.messageList.map(item => item.unRead)
						this.presentReadState = readNumberList.reduce((accumulator, currentValue) =>
							accumulator + currentValue, 0);
						if (this.presentReadState > 0) { // 若是消息数量大于0的话,初始化一下inline-msg状态
							uni.setStorageSync("inline-msg", true)
						}
					}
				})
			},
		},

		onShow() {
			this.loadsocket()
			this.getMessageList()
			// 父子传参方法也不好用,message组件中没有onShow方法,而且watch监听不到props
			// message为组件,其他方法不太好用,使用事件总线发送全局事件 refreshMessageList
			uni.$emit('refreshMessageList');
			this.tabBar.list[2].hasUnreadMessage = uni.getStorageSync("inline-msg")
		},

		mounted() {
			this.tabBar.list[2].hasUnreadMessage = uni.getStorageSync("inline-msg")
		},
	}
</script>

其中一个子组件 Message文章来源地址https://www.toymoban.com/news/detail-846266.html

<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>

到了这里,关于记录一下小程序自定义导航栏消息未读已读小红点,以及分组件的消息数量数据实时读取的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 小程序导航穿透且自定义导航栏

    需求 实现小程序隐藏头部导航栏,且导航栏穿透无高度,并且要定义返回事件 在 app.json 里面把 “navigationStyle” 设置为 “custom” 这样子之后页面就只会保留右上角胶囊按钮。

    2024年02月16日
    浏览(37)
  • 记录一下【微信小程序skyline模式的一些坑】

    最近在用这个skyline渲染模式开发页面,记录一下遇到的一些坑,总结一下使用体验: 快跑!run! 总结我遇到的不能接受的地方 无法使用css变量 ,基于 unocss或tailwind 原子化css,需要对css变量做额外的处理,有点难受了; wxss使用import导入公共wxss,不生效 ,难受加剧; 最新的

    2024年02月16日
    浏览(105)
  • 小程序自定义导航栏

    app.json文件下 app.js文件 组件文件components文件夹下新增navBar文件 index.js index.wxss index.wxml 使用 js

    2024年02月16日
    浏览(42)
  • 记录一下:uniapp小程序分包后引用组件报错问题

     具体遇到的场景是这样的,我当前文件是在主包中,但是引入的这几个组件是在分包下面,于是就造成了引入错误,我曾尝试者用绝对跟相对路径引入缺仍然报错 最终看到一个贴记录的是: 小程序分包后,主包应该是不能引用分包的任何资源,分包可以引用主包的任何资源

    2024年02月15日
    浏览(43)
  • 微信小程序自定义顶部导航,滚动页面顶部导航颜色渐变

    微信小程序自定义顶部导航栏,使背景图置顶;当向上滚动页面时,实现顶部导航颜色渐变 实现方法 代码如下(示例): 提示:由于不同的手机机型顶部导航高度不一样,所有要获取手机的信息 总共三步: 1、初始化获取顶部导航信息 2、顶部导航文字上方通过view占位,同

    2024年02月11日
    浏览(55)
  • 小程序自定义导航自适应组件

    小程序开发中,有时我们不需要自带的导航栏,那就需要自己写一个这样的导航栏。 pages/index 需要现在app.js启动的时候获取一些信息 app.js 下面是组件代码 component/navbar.js component/navbar.wxml component/navbar.wxss wx.getSystemInfoSync(); // 获取到状态栏的信息 wx.getMenuButtonBoundingClientRect()

    2024年01月18日
    浏览(46)
  • Uniapp-小程序自定义导航栏

    制作小程序页面时候发现原生导航栏有一定的高度是没有背景渲染的会出现这种情况 但是我们需要的是 小程序的原生导航栏存在。一般可以使用 纯色填充顶部栏 可以直接使用navigationBarBackgroundColor完成 在style中添加 \\\"navigationBarBackgroundColor\\\": \\\"#FED000\\\" 但是业务需求需要添加自

    2024年02月05日
    浏览(34)
  • uniapp小程序自定义头部导航

    我们在开发小程序时,自带的头部导航样式往往不能满足需求,故只能自定义导航,接下来简要介绍下如何实现: 1. 去除自带的头部导航 要想自定义头部导航,首先要到pages.json文件夹中,找到对应页面,然后在style中写上代码: 2.封装自定义的头部导航 一个小程序,可能会

    2024年02月11日
    浏览(56)
  • 微信小程序自定义底部导航栏

    微信小程序自定义底部导航栏,原生实现,不包含其他任何第三方组件,比较干净,开箱即用 效果预览: 可自定义底部导航栏列表样式 可自定义每个菜单的默认、激活后的图标和文字样式 可自定义是否添加中间的大图标菜单,当然也可自定义大图标的默认与激活样式 可自

    2024年02月07日
    浏览(55)
  • 微信原生小程序自定义顶部导航

    都2023了,自定义顶部导航应该不是什么新鲜事了,这里只是简单记录下 微信自己也提供了自定义顶部导航 navigation-bar ,大概看了下,可配置的也不少,所以看需求了,如果简单可以采用微信提供的,老规矩,先看效果 状态栏高度(getSystemInfoSync),就是手机顶部网络那块的

    2024年02月15日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包