超详细版:HBuilderX中实现uniapp小程序动态tabBar

文章讲述了在开发过程中如何根据用户登录状态动态展示tabBar。首先在Page.json配置所有可能的页面,然后隐藏导航栏,定义publicBar和selfBar公共及个人导航数据,使用Vuex管理用户信息和tabBar列表,根据用户状态决定显示哪个tabBar。最后创建自定义tabBar组件并在各页面使用。
摘要由CSDN通过智能技术生成

开发过程中遇到了动态tabBar的需求,用户登录后要根据用户信息动态展示tab栏,这里跟PC端的用户权限页面是一个意思,核心步骤就是:

  1. 先在Page.json文件中tabBar/list数组内配置好所有需要展示的页面,这里只需要在list各对象中设置好pagePath这个必填属性就好(必填属性,不填控制台报错,无法展示导航页面)

"list": [{
        "pagePath": "pages/tabBar/home/home",
      },
      {
        "pagePath": "pages/tabBar/inspect/inspect",
      },
      {
        "pagePath": "pages/tabBar/cart/cart",
      },
      {
        "pagePath": "pages/tabBar/mine/mine",
      }, 
      {
        "pagePath": "pages/tabBar/centerBar/centerBar",
      }
    ]
  1. 隐藏所有tabBar页面对应的.vue页面的导航栏

    onReady() {
      uni.hideTabBar()//隐藏导航栏方法
    }
  1. 根据需求确定publicBar公共导航数据 及 selfBar个人导航数据,需定义如下.js文件:

export const publicBar = [{
    "pagePath": "/pages/tabBar/home/home",
    "iconPath": require("@/static/home_line.png"),
    "selectedIconPath": require("@/static/home_line (1).png"),
    "text": "首页"
  },
  {
    "pagePath": "/pages/tabBar/inspect/inspect",
    "iconPath": require("@/static/car_black.png"),
    "selectedIconPath": require("@/static/car_light.png"),
    "text": "验货"
  }, {
    "pagePath": "/pages/tabBar/cart/cart",
    "iconPath": require("@/static/shopping_cart_line.png"),
    "selectedIconPath": require("@/static/shopping_cart_line (1).png"),
    "text": "购物车"
  }, {
    "pagePath": "/pages/tabBar/mine/mine",
    "iconPath": require("@/static/user_circle_line.png"),
    "selectedIconPath": require("@/static/user_circle_line (1).png"),
    "text": "我的"
  }
]

export const selfBar = [{
  "pagePath": "/pages/tabBar/centerBar/centerBar",
  "iconPath": require("@/static/add_line.png"),
  "selectedIconPath": require("@/static/add_line (1).png"),
  "text": "个人中心"
}]
  1. 根据用户身份或登录状态匹配出需要展示的tabBar页面,建立vuex进行存储

//导入上方定义好的两组tabBar数据
import {
  publicBar,
  selfBar
} from '@/utils/myTabBar.js';
export default {
  namespaced: true,
  state: {
    userInfo: uni.getStorageSync('userInfo') || {},
    tabBarList: publicBar,
    activeIndex: uni.getStorageSync('acIndex') || 0,  //本地化index 控制页面刷新导航高亮位置不变
  },
  mutations: {
    //用户登录后触发次方法存储用户信息
    setUserInfo(state, obj) {
      uni.setStorageSync('userInfo', obj)
      console.log(obj, 'storage');
      state.userInfo = obj;
      //判断用户是否登录,登录后将个人导航栏加入要展示的数组中(大家根据需求来做)
      obj.nickName && (state.tabBarList = [...publicBar, ...selfBar])
    },
    //用户改变当前高亮的导航栏后进行记录
    changeIndex(state, index) {
      uni.setStorageSync('acIndex', index)
      state.activeIndex = index
    }
  },
  getters: {
    //根据用户信息的改变俩获取到最新的导航栏数据
    barList(state) {
      return state.userInfo.nickName ? [...publicBar, ...selfBar] : state.tabBarList
    }
  }
}
  1. 自定义tabBar组件:在根目录下创建components/myTabBar/myTabBar.vue文件

  1. 引入vuex中tabBar数据,搭建tabBar结构:

<template>
  <view class="tabBarList">
    <view class="Item" v-for="(item, index) in barList" :key="index" @click="changeActive(item, index)">
      <image class="img" :src="activeIndex === index ? item.selectedIconPath : item.iconPath"></image>
      <view style="font-size: 12px;">{{ item.text }}</view>
    </view>
  </view>
</template>


<script>
import { mapState, mapMutations, mapGetters } from 'vuex'
export default {
  data() {
    return {}
  },
  computed: {
    ...mapState('user', ['activeIndex']),
    ...mapGetters('user', ['barList'])
  },
  methods: {
    ...mapMutations('user', ['changeIndex']),
    //用户触发tabBar改变当前高亮并跳转至对应页面
    changeActive(item, index) {
      this.changeIndex(index)
      uni.switchTab({
        url: item.pagePath
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.tabBarList {
  display: flex;
  position: fixed;
  bottom: 0;
  width: 100%;
  height: 100rpx;
  border: 1px solid #ccc;
  overflow: hidden;
  .Item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    .img {
      width: 50rpx;
      height: 50rpx;
    }
  }
}
</style>
  1. 最后一步:在各导航栏.vue文件中使用该组件即可

<template>
  <view>
    <tabBarList></tabBarList>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        
      };
    },
    onReady() {
      uni.hideTabBar()
    }
  }
</script>

<style lang="scss">

</style>
  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
1. 在uniapp项目的pages文件夹下创建一个tabbar文件夹,里面放置每个tab对应的页面。 2. 在App.vue添加自定义tabbar,代码如下: ```vue <template> <div class="app"> <tabbar :list="tabbarList" :active="active" @change="tabbarChange"></tabbar> <router-view></router-view> </div> </template> <script> import tabbar from "@/components/tabbar.vue"; export default { components: { tabbar, }, data() { return { active: 0, tabbarList: [ { icon: "home", text: "首页", path: "/pages/tabbar/home/home", }, { icon: "cart", text: "购物车", path: "/pages/tabbar/cart/cart", }, { icon: "user", text: "我的", path: "/pages/tabbar/user/user", }, ], }; }, methods: { tabbarChange(index) { this.active = index; uni.switchTab({ url: this.tabbarList[index].path, }); }, }, }; </script> ``` 3. 在components文件夹下创建tabbar.vue组件,代码如下: ```vue <template> <div class="tabbar"> <div class="tabbar-item" v-for="(item, index) in list" :key="index" @click="change(index)"> <i :class="'iconfont icon-' + item.icon" :style="{color: index === active ? activeColor : inactiveColor}"></i> <span :style="{color: index === active ? activeColor : inactiveColor}">{{item.text}}</span> </div> </div> </template> <script> export default { props: { list: { type: Array, default: () => [], }, active: { type: Number, default: 0, }, activeColor: { type: String, default: "#007AFF", }, inactiveColor: { type: String, default: "#8E8E93", }, }, methods: { change(index) { if (index !== this.active) { this.$emit("change", index); } }, }, }; </script> <style> .tabbar { display: flex; justify-content: space-between; align-items: center; height: 50px; background-color: #fff; border-top: 1px solid #e5e5e5; position: fixed; bottom: 0; left: 0; right: 0; z-index: 999; } .tabbar-item { display: flex; flex-direction: column; align-items: center; justify-content: center; flex: 1; font-size: 12px; cursor: pointer; } .tabbar-item i { font-size: 22px; margin-bottom: 2px; } </style> ``` 4. 在manifest.json配置tabBar,代码如下: ```json { "tabBar": { "color": "#8E8E93", "selectedColor": "#007AFF", "backgroundColor": "#ffffff", "list": [ { "pagePath": "pages/tabbar/home/home", "text": "首页", "iconPath": "static/tabbar/home.png", "selectedIconPath": "static/tabbar/home-active.png" }, { "pagePath": "pages/tabbar/cart/cart", "text": "购物车", "iconPath": "static/tabbar/cart.png", "selectedIconPath": "static/tabbar/cart-active.png" }, { "pagePath": "pages/tabbar/user/user", "text": "我的", "iconPath": "static/tabbar/user.png", "selectedIconPath": "static/tabbar/user-active.png" } ] } } ``` 注意:manifest.jsontabBar配置只是为了在微信小程序显示原生tabbar,不会影响自定义tabbar的显示。而App.vuetabbar组件才是自定义tabbar实现
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值