• uniapp 实现不同用户展示不同的tabbar(底部导航栏)


    目录

    一、背景

    源码地址:包含vue2和vue3版本cheinlu/tabBar_demo_vue

    二、效果展示

    三、前置工作

    四、创建tabbar组件

    五、登录页面根据不同身份进行tabbar切换逻辑

    六、问题拓展


    一、背景

    最近在做一个uniapp开发的小程序遇到一个需求,希望不同用户登录后展示不同的tabbar页面,但是uniapp项目中的pages.json是只有一个list数组的,并且是不能写成动态效果,为了实现这个需求,便自定义了tabbar组件

    备注:本次示例为vue2版本,vue3版本源码可查看以下地址👇

    完整代码地址(包含vue2和vue3版本)👉: cheinlu/tabBar_demo_vue

    二、效果展示

    2.1、角色1:admin账号登录效果

    用户名:admin    密码:123456

    2.2、角色2:tom账户登录效果

    用户名:tom    密码:123456

    三、前置工作

    3.1、将登录页面作为用户进入小程序展示的第一个页面,pages.json文件中的pages数组第一个设为login页面👇

    3.2、pages.json配置tabbar的基本路径(只需路径即可)👇

    1. {
    2. "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
    3. {
    4. "path" : "pages/login/login",
    5. "style" :
    6. {
    7. "navigationBarTitleText": "",
    8. "enablePullDownRefresh": false
    9. }
    10. }
    11. ,{
    12. "path": "pages/index/index",
    13. "style": {
    14. "navigationBarTitleText": "首页"
    15. }
    16. }
    17. ,{
    18. "path" : "pages/warn/warn",
    19. "style" :
    20. {
    21. "navigationBarTitleText": "告警",
    22. "enablePullDownRefresh": false
    23. }
    24. }
    25. ,{
    26. "path" : "pages/my/my",
    27. "style" :
    28. {
    29. "navigationBarTitleText": "我的",
    30. "enablePullDownRefresh": false
    31. }
    32. }
    33. ],
    34. "globalStyle": {
    35. "navigationBarTextStyle": "black",
    36. "navigationBarTitleText": "uni-app",
    37. "navigationBarBackgroundColor": "#F8F8F8",
    38. "backgroundColor": "#F8F8F8"
    39. },
    40. "uniIdRouter": {},
    41. "tabBar": {
    42. "list": [
    43. {
    44. "pagePath": "pages/index/index"
    45. },
    46. {
    47. "pagePath": "pages/warn/warn"
    48. },
    49. {
    50. "pagePath": "pages/my/my"
    51. }
    52. ]
    53. }
    54. }

    四、创建tabbar组件

    4.1、第一步:在项目中创建components文件夹,并在文件夹下创建tabbar组件👇

    tabbar组件具体代码如下:

    1. <script>
    2. export default {
    3. props: {
    4. selectedIndex: { // 当前选中的tab index
    5. default: 0
    6. },
    7. },
    8. data() {
    9. return {
    10. color: "#666666",
    11. selectedColor: "#00BAB2",
    12. list: [],
    13. currentIndex:0,
    14. }
    15. },
    16. created() {
    17. this.currentIndex = this.selectedIndex;
    18. let _this = this
    19. if (uni.getStorageSync('identify') == 'tom') {
    20. //角色1
    21. _this.list = [{
    22. "pagePath": "/pages/index/index",
    23. "iconPath": "/static/tab/home.png",
    24. "selectedIconPath": "/static/tab/home_active.png",
    25. "text": "首页"
    26. },
    27. {
    28. "pagePath": "/pages/my/my",
    29. "iconPath": "/static/tab/my.png",
    30. "selectedIconPath": "/static/tab/my_active.png",
    31. "text": "我的"
    32. }
    33. ]
    34. } else {
    35. //角色2
    36. _this.list = [{
    37. "pagePath": "/pages/index/index",
    38. "iconPath": "/static/tab/home.png",
    39. "selectedIconPath": "/static/tab/home_active.png",
    40. "text": "首页"
    41. },
    42. {
    43. "pagePath": "/pages/warn/warn",
    44. "iconPath": "/static/tab/warn.png",
    45. "selectedIconPath": "/static/tab/warn_active.png",
    46. "text": "告警"
    47. },
    48. {
    49. "pagePath": "/pages/my/my",
    50. "iconPath": "/static/tab/my.png",
    51. "selectedIconPath": "/static/tab/my_active.png",
    52. "text": "我的"
    53. }
    54. ]
    55. }
    56. },
    57. methods: {
    58. switchTab(item, index) {
    59. this.currentIndex = index;
    60. let url = item.pagePath;
    61. uni.redirectTo({url:url})
    62. }
    63. }
    64. }
    65. script>
    66. <style lang="scss">
    67. .tab {
    68. position: fixed;
    69. bottom: 0;
    70. left: 0;
    71. right: 0;
    72. height: 100rpx;
    73. background: white;
    74. display: flex;
    75. justify-content: center;
    76. align-items: center;
    77. padding-bottom: env(safe-area-inset-bottom); // 适配iphoneX的底部
    78. .tab-item {
    79. flex: 1;
    80. text-align: center;
    81. display: flex;
    82. justify-content: center;
    83. align-items: center;
    84. flex-direction: column;
    85. .tab_img {
    86. width: 60rpx;
    87. height: 60rpx;
    88. }
    89. .tab_text {
    90. font-size: 30rpx;
    91. margin-top: 9rpx;
    92. }
    93. }
    94. }
    95. style>

    注意:👉 跳转路径:pagePath以/开头

    说明:tab_img可以修改图标大小,tab_text可以修改文字大小

    4.2、第二步: 在main.js文件中将自定义的tabBar定义为全局组件

    1. //⭐⭐ main.js 文件
    2. import tabBar from "@/components/tabbar/tabbar.vue"
    3. Vue.component('tabBar',tabBar)

    4.3、第三步:在需要使用的页面引入tabbar组件

    1. //如 index页面👇
    2. //如 warn 页面👇
    3. <template>
    4. <view>
    5. 告警
    6. <tabBar selectedIndex = 1>tabBar>
    7. view>
    8. template>
    9. //如 my 页面👇
    10. <template>
    11. <view>
    12. 我的
    13. <tabBar selectedIndex = 2>tabBar>
    14. view>
    15. template>

    4.4、第四步:隐藏pages.json里配置的导航栏,使用封装的tabbar组件,在需要引入tabbar组件的页面进行配置

    1. //如 warn 页面👇 index 和 my 页面也是同样的设置

    五、登录页面根据不同身份进行tabbar切换逻辑

    1. //登录 login 页面👇
    2. <script>
    3. export default {
    4. data() {
    5. return {
    6. //页面上设置的默认账户admin,密码123456
    7. username: 'admin',
    8. password: '123456'
    9. };
    10. },
    11. onShow() {
    12. uni.clearStorageSync('identify')
    13. },
    14. methods: {
    15. login() {
    16. const username = this.username;
    17. const password = this.password;
    18. let identify = '';
    19. // 根据用户名和密码来确定身份
    20. if (username === 'tom' && password === '123456') {
    21. identify = 'tom';
    22. } else if (username === 'admin' && password === '123456') {
    23. identify = 'admin';
    24. } else {
    25. // 用户名或密码错误
    26. console.log('用户名或密码错误');
    27. return;
    28. }
    29. //本地存储
    30. uni.setStorageSync('identify', identify);
    31. // 跳转到首页
    32. uni.switchTab({
    33. url: '/pages/index/index'
    34. });
    35. }
    36. }
    37. };
    38. script>
    39. <style scoped>
    40. .container {
    41. padding: 30rpx;
    42. }
    43. .form-group {
    44. display: flex;
    45. align-items: center;
    46. justify-content: center;
    47. margin-bottom: 30rpx;
    48. }
    49. input{
    50. border: 1rpx solid #00BAB2;
    51. padding: 10rpx;
    52. }
    53. button {
    54. background-color: #00BAB2;
    55. color: white;
    56. border: none;
    57. border-radius: 20rpx;
    58. }
    59. style>

    六、问题拓展

    6.1、问题:当是角色1时,点击tabbar我的页面文字和图标造成颜色闪烁

    6.2、原因:角色1是有两个tabbar ,“我的”页面对应的index值是1,而selectedIndex 被设置为超出角色1 tab 的索引范围。在这种情况下,currentIndex 的默认值为0,而将 selectedIndex 设置为2 会导致 currentIndex 与实际选中的 tab 不一致,进而导致文字和图标显示颜色发生闪烁。

    6.3、解决:在传递 selectedIndex 组件时进行判断,并确保它不会超出角色1 tab 的索引范围

    6.4、重新修改my页面

    1. //👇 my 页面
    2. <script>
    3. export default {
    4. computed: {
    5. //判断是什么角色
    6. selectedTabIndex() {
    7. return uni.getStorageSync('identify') === 'tom' ? 1 : 2;
    8. }
    9. },
    10. onShow() {
    11. uni.hideTabBar({
    12. animation:false
    13. })
    14. },
    15. }
    16. script>

    PS:如果对你有帮助的话,请给个赞,有问题欢迎大家在评论区讨论。ღ( ´・ᴗ・` )  ღ( ´・ᴗ・` ) 

    最后:👏👏😊😊😊👍👍 

  • 相关阅读:
    C语言中拟合线性方程(最小二乘法)
    小程序笔记2
    New的原理
    perl从文件中搜索关键字
    15:00面试,15:08就出来了,问的问题有点变态。。。
    Linux 简要命令记录
    百度工程师眼中的云原生可观测性追踪技术
    spark临时文件较大问题处理
    【20220912】电商业务的核心流程
    记录C++类中的一次函数调用
  • 原文地址:https://blog.csdn.net/weixin_71403100/article/details/133042608