赞
踩
解决小程序自定义底部菜单切换闪动
业务上可能会有一个需求使用自定义底部菜单相信会有很多人遇到过这个需求
但是自定义底部菜单会有一个问题,在点击切换页面的时候底部菜单会重新加载,导致页面闪动,比较影响用户的体验性;
我采用的解决办法是建立一个公共的页面,所有底部菜单的对应页面采用组件的方法,这样可以解决底部菜单切换时闪动的问题;
我用的是uni开发的代码上可能与原生小程序有所差异,整体思路其实是一样的
头部我用的是自定义的头部,适配了不同机型(可能会有偏差)
接下来开始吧
1.新建一个indexRouter.vue的页面
<template> <view style="position: relative;" :class="nowchos==1?'bg_index_top':''"> <home ref='home' v-if="nowchos == 1"></home> <curriculum v-if="nowchos == 2"></curriculum> <business v-if="nowchos == 3"></business> <circle v-if="nowchos == 4"></circle> <mine ref='mine' v-if="nowchos == 5"></mine> <view class="bottomboxs"> //底部组件 <navbottom :nowchos='nowchos' @botomchos='botomchos'></navbottom> </view> </view> </template> <script> import navbottom from '@/components/navbottom.vue'//引入 底部菜单组件 import home from './index/index.vue'// 引入 首页 import business from './business.vue'// 同上 引入相关页面 import circle from './circle.vue'// 同上 引入相关页面 import mine from './mine.vue'// 同上 引入相关页面 import curriculum from './curriculum.vue'// 同上 引入相关页面 export default { components: {//在这里注册相应的组件 home, business, circle, mine, curriculum, navbottom }, data() { return { nowchos: 1, //当前选择了那个底部菜单 navtit: '页面标题', full: false, //是否全面屏 bigscroll: false, //是否固定头部 } }, watch: { nowchos(e) { console.log(e);//可以监听 底部菜单的切换 } }, onPullDownRefresh() {//监听页面刷新 可以实现刷新重新请求组件里的接口重新渲染 if(this.nowchos == 1){ this.$refs.home.getlist() setTimeout(()=>{ uni.stopPullDownRefresh() },500) }else if(this.nowchos == 2){ }else if(this.nowchos == 3){ }else if(this.nowchos == 5){ } }, onLoad(e) { let that = this; //判断是否是全面屏 uni.getSystemInfo({ success: function(res) { if (res.model.search(/iPhone\sX|iPhone\s11|iPhone\s12|iPhone\s13/) != -1) { that.full = true } else { that.full = false } } }); }, onPageScroll(e) { //如果高度超过多少 固定住自定义头部 if (e.scrollTop > 60) this.bigscroll = true else this.bigscroll = false }, methods: { botomchos(e) { this.nowchos = e if (e == 1) { this.navtit = '我是菜单1' } else if (e == 2) { this.navtit = '我是菜单2' } else if (e == 3) { this.navtit = '我是菜单3' } else if (e == 4) { this.navtit = '我是菜单4' } else if (e == 5) { this.navtit = '我是菜单5' } } } } </script> <style lang="scss"> .bg_index { position: absolute; top: 0; left: 0; width: 580rpx; height: 474rpx; background: rgba(172, 126, 255, 0.1); filter: blur(50rpx); } .bg_index_top{ background: linear-gradient(180deg, #FFFFFF 0%, #F6F6F6 13%, #F0F0F0 50%, #F7F7F7 100%); } .headerfix { position: fixed !important; top: 0; left: 0; background-color: #FFFFFF; z-index: 3 !important; .title { color: #000000 !important; } } .fullcss { padding-top: 100rpx !important; } .headerBox { width: 100vw; position: relative; box-sizing: border-box; padding: 60rpx 30rpx 20rpx; transition: 500ms all; z-index: 2; .title { position: absolute; left: 50%; font-size: 16px; font-weight: 500; color: #000000; transform: translate(-50%, 0%); } } .bottomboxs{ position: relative; z-index: 99; } </style>
2.新建一个底部组件navbottom.vue
<template> <view class=""> <view class="flexcenter navmainbox" :style="full?'height:130rpx;padding-bottom:30rpx;z-index:100;':''"> <view v-for="(item,index) in list[0]" :key="index" class="navcont" @click="gonavs(item,index)"> <image style="width: 52rpx;height: 52rpx;" :src="nowchos==(index+1)?item.chosicon:item.icon" ></image> <view :class="nowchos==(index+1)?'navchosboxb':''">{{item.name}}</view> </view> </view> //防止 固定的底部菜单遮挡页面上的内容 <view class="navmainbox" style="position: relative;opacity: 0;z-index: 0;" :style="full?'height:130rpx':''"></view> </view> </template> <script> export default { name: 'navbottom', data() { return { full:false,//是否全面屏 list: [ [{ name: '首页',//底部菜单展示文件 icon: "/static/business/home.png",//底部菜单未激活时的图标 chosicon: '/static/business/homes.png',//激活的图标 //path: "/pages_business/index/index"//需要跳转的路径(不需要加) }, { name: '页面', icon: '/static/business/class.png', chosicon: '/static/business/classs.png', //path: '/pages_business/curriculum' }, { name: '页面', icon: '/static/business/business.png', chosicon: '/static/business/businesss.png', //path: '/pages_business/business' }, { name: '页面', icon: '/static/business/chat.png', chosicon: '/static/business/chats.png', //path: '/pages_business/circle' }, { name: '我的', icon: '/static/business/mine.png', chosicon: '/static/business/mines.png', //path: '/pages_business/mine' } ] ],//底部菜单数组 } }, props: { nowchos: {//接收当前激活的底部的下标 type: Number, default: 1 } }, mounted() { let that = this; that.$nextTick(() => { //判断是否是全面屏 uni.getSystemInfo({ success: function (res) { if (res.model.search(/iPhone\sX|iPhone\s11|iPhone\s12|iPhone\s13/) != -1) { that.full = true } else { that.full = false } } }); }) }, methods: { gonavs(e,cindex) { if(index==1){ //告诉父级要跳转去哪 this.$emit('botomchos',cindex+1) } } } } </script> <style lang="less" scoped> view{ box-sizing: border-box; } .navmainbox { position: fixed; bottom: 0; left: 0; width: 100vw; height: 112rpx; background-color: #FFFFFF; border-top: 1rpx solid #ebebeb; box-shadow: 0 2rpx 12rpx 0 rgba(0, 0, 0, 0.1); font-size: 24rpx; padding: 14rpx 0 10rpx; z-index: 5; .navcont { width: 25%; color: #B0B0B0; text-align: center; } } .navchosbox { color: #F56C6C!important; } .navchosboxb{ color: #0059FF!important; } .flexcenter{ display: flex; justify-content: center; align-items: center; } </style>
如果有 遗漏 或者有 改善 的地方可以指出
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。