uniapp-自定义底部切换栏
uniapp-自定义底部切换栏
自定义底部切换栏
首先我们必须清楚一个小的配置
要去掉默认的导航栏,即设置navigationStyle为custom;
预览
最后写出来的方式可以看出来最后就是这个样子
导航栏参数解析
🐟 globalStyle:默认页面的窗口表现
我们看到底部导航栏上面有个添加的这种特殊的标记,一般我们是没办法直接在tabBar之中进行配置的,这个时候我们就只能自己进行定义开发一个特殊类型的导航栏
想要自定义导航栏,那么我们就需要自己进行定义配置,先认识一下简单的参数
"path": "pages/user/user"
:页面路径。"navigationBarTitleText": "我的"
:设置页面标题,在使用自定义导航栏的时候这个属性不会生效。"enablePullDownRefresh": false
:禁用下拉刷新功能。"navigationStyle": "custom"
:启用自定义导航栏
所以我们首页正常就是这样子
{
"path": "pages/tabBar/index/index",
"style": {
"navigationBarTitleText": "首页",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
这里我们使用tabbar告诉微信哪些页面属于tabbar页面,也可以同时在这些页面使用switchBar
自定义导航栏实现
接下来我们建立一个fooBar
组件,然后在我们的页面之中直接引用
component =>fooBar=> import('@/components/fooBar/fooBar.vue')
vue2写法
vue2+webpack
之前我们在vue2之中结合webpack的方式可能是这样子的
<script>
export default {
props: {
/* 当前导航栏 */
currPage: {
type: Number,
default: 0
}
},
data() {
return {
curItem: 0, // 当前所选导航栏
// 导航栏列表
tabbarList: [
{
id: 0,
pagePath: "/pages/tabBar/index/index",
iconPath: "/static/tabBar/home.png",
selectedIconPath: "/static/tabbar/homeact.png",
text: "首页",
centerItem: false
},
{
id: 1,
pagePath: "/pages/tabBar/center/center",
iconPath: "/static/tabbar/center.png",
selectedIconPath: "/static/tabbar/centeract.png",
text: "分类",
centerItem: false
},
{
id: 2,
pagePath: "/pages/tabBar/tougao/index",
iconPath: "/static/tabBar/tougaoact.png",
selectedIconPath: "/static/tabBar/tougao.png",
text: "发布",
centerItem: true
},
{
id: 3,
pagePath: "pages/tabBar/list/list",
iconPath: "/static/tabbar/find.png",
selectedIconPath: "/static/tabbar/findact.png",
text: "榜单",
centerItem: false
},
{
id: 4,
pagePath: "/pages/tabBar/user/user",
iconPath: "/static/tabbar/user.png",
selectedIconPath: "/static/tabbar/useract.png",
text: "我的",
centerItem: false
},
]
};
},
mounted() {
this.curItem = this.currPage; // 当前所选导航栏
// #ifdef H5
uni.hideTabBar(); // 隐藏 tabBar 导航栏
// #endif
},
methods: {
/* 导航栏切换 */
changeItem(e) {
console.log('点击',e);
// 中间凸起按钮
if (e.id === 1) {
// todo
return;
}
uni.switchTab({ url: e.pagePath }); // 跳转到其他 tab 页面
}
}
};
</script>
vue3写法
自定义底部切换栏
vue3+vite
之前我们的底部切换栏采用的是vue2的方式写法,接下来我们就实现并且更换成vue3+vite的方式
uni.switchTab(OBJECT)的作用 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
//方式一 函数类型式跳转
function changeItem(e) {
console.log(e,'.target.value');
console.log(e.id,'.target.value');
// 中间凸起按钮
if (e.id === 2) {
// todo
return;
}
uni.switchTab({ url:e.pagePath }); // 跳转到其他 tab 页面
}
//方式二 箭头类型式跳转
const changeItem = (e) => {
console.log(e,'.target.value');
console.log(e.id,'.target.value');
if (e.id === 2) {
// todo
return;
}
uni.switchTab({
url: e.pagePath,
});
};
封装组件
现在我们可以看到,点击出来的本质其实是这个页面,那么如何进行底部切换或者说隐藏底部菜单呢
接下来我们封装并作出一些优化,让这个底部切换栏组件化,让我们的底部菜单栏更加的贴合现在我们使用
去掉底部菜单栏
首先,我们给写成一个组件,在每个页面加载的时候去掉显示的底部菜单栏,那么方法就是加载的时候隐藏菜单,这里需要注意‘引入的地方’
import { onLoad } from "@dcloudio/uni-app";
onLoad(() => {
uni.hideTabBar();
});
进行每个页面的组件传值和引入
<foo-bar :current="1"></foo-bar>
<foo-bar :current="2"></foo-bar>
<foo-bar :current="3"></foo-bar>
<foo-bar :current="4"></foo-bar>
function changeNav(index) {
console.log("底部导航:", index);
}
当我们需要切换底部监听栏的时候使用
<foo-bar :current="5" @change="changeNav"></foo-bar>
生命周期处理
生命周期问题
接下来我们尝试一下
点击分类,这里我们显示正常,可是点击榜单怎么回事呢
第一次点击榜单的时候我们这里没反应,只有第二次点击才能传过去
这是怎么回事呢,这里我们再次看一下uniapp之中vue3之中的生命周期
在 Vue 3 中使用 UniApp 时,UniApp 提供了类似小程序的生命周期钩子,比如 onShow
和 onLoad
。
我们分析一下它们的优先级和触发时机:
- onLoad 生命周期钩子:
onLoad
生命周期钩子在页面加载时触发,就是页面首次加载时执行。- 一般用于页面初始化(数据加载、参数解析)。
- onShow 生命周期钩子:
onShow
生命周期钩子在页面显示时触发,包括页面首次加载时也会触发。- 当页面被切换到前台时(比如从其他页面返回到当前页面),也会触发
onShow
方法,也就是处理(每次显示更新的数据和刷新)
优先级和触发时机的关系:
- 在页面首次加载时,
onLoad
钩子首先触发,用于页面的初始化。 - 随后页面显示时(比如从其他页面返回),会依次触发
onShow
钩子,用于处理页面每次显示时需要执行的逻辑。
因此, onLoad
用于页面初始化完成然后 onShow
展示执行
onLoad
生命周期剖析
这里用白话文解释一下onLoad
执行的整个过程,结合vue的v-if
的销毁来进行理解:
// 加载
onLoad(() => {
uni.hideTabBar();
});
当我们第一次点击的时候
组件进行了赋值操作curItem.value=e.id;
这个时候进行了切换``uni.switchTab() 方式来创建组件,这个时候组件刚刚加载出来,所以组件此刻的状态其实还是在上次状态中
第二次点击
组件这个时候还是拿到给的赋值,也就是上次curItem.value=e.id;
组件切换``uni.switchTab(),这个时候组件已经加载出来,所以组件此刻的状态跟上次对上
总的来说就是后来总是慢一拍
onShow
生命周期剖析
那么如果我们把上面的onLoad改成 onShow
展示执行呢
onShow(() => {
uni.hideTabBar();
});
我们这里直接在页面打印出来看看
这里我们可以看到我们的id是这样子的
点击第一次分类
以后
在一瞬间竟然进行了短暂的切换,随后又再次切换回去,不过可以看到我们的方法已经成功了
点击第二次分类
以后
还是那个页面,但是我们页面对应的值已经可以看到切换过去了,带动的我文字也正常显示
过程:
每次进入页面都执行了一下组件初始化
如何解决呢?
思路一:把切换的方式交出去
之前我们写切换的时候,这个切换总是放在我们公共组件之中,现在我们把这个方法交给上头,提交出去,让分页面之中进行控制。
那这个时候就是页面onLoad以后,我们在这个页面切换,那必然可以。
/* 导航栏切换 --更改前 */
const changeItem = (e) => {
console.log(e, '.target.value');
// console.log(e.id, '.target.value');
curItem.value=e.id;
if (e.id === 2) {
// todo
return;
}else{
uni.switchTab({
url: e.pagePath,
success() {
emits("change", e);
},
});
}
};
/* 导航栏切换 ---更改以后 */
const changeItem = (e) => {
console.log(e, '.target.value');
// console.log(e.id, '.target.value');
curItem.value=e.id;
if (e.id === 2) {
// todo
return;
}else{
emits("change", e);
// uni.switchTab({
// url: e.pagePath,
// success() {
// emits("change", e);
// },
// });
}
};
这里记得把我们状态每次的判断给改一下
抽离我们的方法
/* 导航栏切换 */
const changeItem = (e) => {
console.log(e, '.target.value');
// console.log(e.id, '.target.value');
curItem.value=e.id;
if (e.id === 2) {
// todo
return;
}else{
emits("change", e.id);
if(curItem.value == 0){
uni.switchTab({
url: '/pages/tabBar/index/index'
})
}else if(curItem.value == 1){
uni.switchTab({
url: '/pages/tabBar/center/center'
})
}else if(curItem.value == 3){
uni.switchTab({
url: '/pages/tabBar/list/list'
})
}else if(curItem.value == 4){
uni.switchTab({
url: '/pages/tabBar/user/user'
})
}else{
}
}
};
现在再次进行尝试,毫无问题
思路二 使用状态存储
这里还有一种比较好的思路,就是pinia的持久化存储,不过我们切换部分暂时比较简单一些,这个可以稍后放入我们的优化部分之中
优化
这里我们优化一下,可以把其他所有组件的onLoad
隐藏
uni.hideTabBar();
这个方法写到公共组件之中
把其他的加载都拿到公共组件中
这里我们优化底部切换栏完毕!
问题归纳处理和优化
(1)tabBar配置必须已经配置在pages之中
这里需要注意,下面tabBar配置的页面必须已经在pages之中配置好,不然就会报错
解决方式: 只要对应上即可
(2)uview-ui的使用 (这里我们放弃踩这个坑)
1、在根目录uview-ui中放入组件 2、在main.js
之中进行全局引入和使用
// 引入全局uView
import uView from 'uview-ui'
Vue.use(uView);
(3)遇到的闪烁问题的解决
在这个过程的开发之中我们也遇到了问题
在pages.json 中设置隐藏自带的 tabbar 导航栏
这里我们需要在 pages.json配置一下,防止每次都闪烁页面
"tabBar": {
"custom": true,
}
"custom": true, // 开启自定义tabBar(不填每次原来的tabbar在重新加载时都回闪现)
结果设置这个以后,我们的页面跳转反而出错,最后我们还是隐藏掉
- 点赞
- 收藏
- 关注作者
评论(0)