MainTabBar组件在软件下方展示了四个主选项卡:首页(Home)、分类(Category)、购物车(Cart)、我的(Profile),每个选项对应一个页面、一个组件。总体来看,MainTabBar可以看做由一个容器+若干个item组成,所以我们把单个item看做一个组件,把容器看作另一个组件,然后在MainTabBar组件中使用它们,最后在App.vue中使用MainTabBar。(因为无论路由切换到哪里,MainTabBar始终会被显示。)

 

首先来看单个item对应的组件tabBarItem。按照惯例,每个item应该包含小图标+下方文字即可,不过我们这里为每个item准备了两个小图标(另一张是当前item被选中时的高亮颜色版本)。由于使用什么图片、什么文字需要在使用时决定,所以把它们全部设为具名插槽:

<template>
  <div class="tab-bar-item" @click="itemClick">
    <div v-if="!isActive"><slot name="item-icon"></slot></div>
    <div v-else><slot name="item-icon-active"></slot></div>
    <div :style="activeStyle"><slot name="item-text"></slot></div>
  </div>
</template>

使用tabBarItem组件:

    <tab-bar-item path="/home">
      <img slot="item-icon" src="~assets/img/tabbar/home.svg" alt="">
      <img slot="item-icon-active" src="~assets/img/tabbar/home_active.svg" alt="">
      <div slot="item-text">首页</div>
    </tab-bar-item>

当某个选项被点击后,会触发itemClick方法,所以最直接的效果就是当前路由被替换成被点击选项对应的路由,即path属性,该属性于每个tabBarItem被创建时从外部传入,值分别为“/home”、“/category”、“/cart”和“/profile”。

      itemClick() {
        this.$router.replace(this.path)
      }

此外,被点击的选项也会发生一些变化——

1、切换高亮图标,通过v-if和v-else来实现,isActive默认为false,此时显示普通图标,如果isActive变为true则切换高亮图标。isActive是一个计算属性,如果this.$router.path中包含this.path,说明当前选项对应的页面被显示,则把isActive置为true。

      isActive() {
        return this.$route.path.indexOf(this.path) !== -1
      }

2、改变字体颜色,通过动态添加style来实现。

      activeStyle() {
        return this.isActive ? {color: this.activeColor} : {}
      }

高亮后的颜色也可以设为动态的,在使用时指定,这样每个item点击后可以显示不同的颜色。

    props: {
      path: String,
      activeColor: {
        type: String,
        default: 'red'
      }
    }

 

接下来的容器组件TabBar比较简单,它无需任何js代码,只需要提供一个插槽,然后给插槽外部套的div设置弹性容器属性以及fixed定位。(因为滚动对TabBar的位置没有影响。)

<template>
  <div id="tab-bar">
    <slot></slot>
  </div>
</template>

 

第三步,在包装组件MainTabBar(自己取得名字,因为它没有什么特殊功能,只是因为使用上面两个组件的代码太多,为了防止App.vue太臃肿,才多加了这么一层。)中注册并使用这两个组件,在TabBar中插入tabBarItem,在每个tabBarItem中插入图标和文字。

<template>
  <tab-bar>
    <tab-bar-item path="/home">
      <img slot="item-icon" src="~assets/img/tabbar/home.svg" alt="">
      <img slot="item-icon-active" src="~assets/img/tabbar/home_active.svg" alt="">
      <div slot="item-text">首页</div>
    </tab-bar-item>
    ...
  </tab-bar>
</template>

 

最后,在App.vue中注册并使用MainTabBar。

<template>
  <div id="app">
    <keep-alive exclude="Detail">
      <router-view></router-view>
    </keep-alive>
    <main-tab-bar></main-tab-bar>
  </div>
</template>

 

posted on 2021-06-23 22:43  springxxxx  阅读(130)  评论(0编辑  收藏  举报