168 lines
3.4 KiB
Vue
168 lines
3.4 KiB
Vue
<template>
|
|
<u-tabbar
|
|
v-if="show"
|
|
:value="currentIndex"
|
|
:show="true"
|
|
:bg-color="style.backgroundColor"
|
|
:border-top="style.borderTop"
|
|
:fixed="true"
|
|
:height="style.height"
|
|
:list="formattedTabList"
|
|
@change="handleTabChange"
|
|
>
|
|
</u-tabbar>
|
|
</template>
|
|
|
|
<script>
|
|
import tabbarConfig from "@/config/tabbar.config.js";
|
|
|
|
export default {
|
|
name: "TabBar",
|
|
props: {
|
|
// 当前页面路径(可选)
|
|
currentPath: {
|
|
type: String,
|
|
default: "",
|
|
},
|
|
// 是否显示 TabBar
|
|
show: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
currentIndex: 0,
|
|
tabList: tabbarConfig.tabs,
|
|
style: tabbarConfig.style,
|
|
};
|
|
},
|
|
computed: {
|
|
// 格式化为 uview tabbar 所需格式
|
|
formattedTabList() {
|
|
return this.tabList.map((item) => ({
|
|
text: item.text,
|
|
iconPath: item.icon,
|
|
selectedIconPath: item.activeIcon,
|
|
pagePath: item.pagePath,
|
|
count: item.badge || 0,
|
|
isDot: item.dot || false,
|
|
}));
|
|
},
|
|
},
|
|
watch: {
|
|
// 监听 currentPath 变化
|
|
currentPath: {
|
|
handler(newPath) {
|
|
if (newPath) {
|
|
this.updateActiveTab(newPath);
|
|
}
|
|
},
|
|
immediate: true,
|
|
},
|
|
},
|
|
mounted() {
|
|
this.initActiveTab();
|
|
},
|
|
methods: {
|
|
/**
|
|
* 初始化激活的 tab
|
|
*/
|
|
initActiveTab() {
|
|
const path = this.currentPath || this.getCurrentPagePath();
|
|
this.updateActiveTab(path);
|
|
},
|
|
|
|
/**
|
|
* 更新激活的 tab
|
|
*/
|
|
updateActiveTab(path) {
|
|
const index = this.tabList.findIndex((item) =>
|
|
this.isPathMatch(path, item.pagePath)
|
|
);
|
|
if (index !== -1) {
|
|
this.currentIndex = index;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 路径匹配判断
|
|
*/
|
|
isPathMatch(currentPath, targetPath) {
|
|
const normalize = (path) => path.replace(/^\//, "");
|
|
return normalize(currentPath) === normalize(targetPath);
|
|
},
|
|
|
|
/**
|
|
* 获取当前页面路径
|
|
*/
|
|
getCurrentPagePath() {
|
|
const pages = getCurrentPages();
|
|
console.log('pages',pages);
|
|
|
|
if (pages.length > 0) {
|
|
return "/" + pages[pages.length - 1].route;
|
|
}
|
|
return "";
|
|
},
|
|
|
|
/**
|
|
* 处理 tab 切换
|
|
*/
|
|
handleTabChange(index) {
|
|
if (this.currentIndex === index) {
|
|
this.$emit("reclick", this.tabList[index].pagePath, index);
|
|
return;
|
|
}
|
|
|
|
const targetTab = this.tabList[index];
|
|
if (!targetTab) return;
|
|
|
|
this.currentIndex = index;
|
|
this.$emit("change", targetTab.pagePath, index);
|
|
|
|
// 跳转
|
|
this.navigateToTab(targetTab.pagePath);
|
|
},
|
|
|
|
/**
|
|
* 跳转到 tab 页面
|
|
*/
|
|
navigateToTab(url) {
|
|
uni.switchTab({
|
|
url,
|
|
fail: () => {
|
|
// 降级方案
|
|
uni.reLaunch({ url });
|
|
},
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 设置角标
|
|
* @param {number} index - tab 索引
|
|
* @param {string|number} badge - 角标内容
|
|
*/
|
|
setBadge(index, badge) {
|
|
if (this.tabList[index]) {
|
|
this.$set(this.tabList[index], "badge", badge);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 显示/隐藏小红点
|
|
* @param {number} index - tab 索引
|
|
* @param {boolean} show - 是否显示
|
|
*/
|
|
setDot(index, show) {
|
|
if (this.tabList[index]) {
|
|
this.$set(this.tabList[index], "dot", show);
|
|
}
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style scoped lang="scss"></style>
|
|
|