TabBar组件的封装

封装思路

一. 分层封装

第一层由选择项内容组成(如首页、分类、购物车、个人等)

第二层由每一个选择项包含的内容(一般为活跃时显示的图片、不活跃时显示的图面以及该选项的文字描述)

二. 插槽占位

需要填充内容的地方均用插槽占位,以便按需填充

三. 达到目的

适配任何一个移动端app项目,以及适配任何选择项个数

第一层组件TabBar

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

<script>
export default {
  name: "TabBar"
};
</script>

<style>
  #tab-bar {
    display: flex;
    background-color: #f6f6f6;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    box-shadow: 0 -1px 1px 0 rgba(100, 100, 100, 0.2);
  }
</style>

第二层组件TabBarItem

<template>
  <div class="tab-bar-item" @click="itemClick">
    <div v-if="!isActive">  // 具名插槽外层包裹div为了避免被替换时,设置的属性也被替换
      <slot name="item-icon"></slot>
    </div>
    <div v-else>
      <slot name="item-icon-active"></slot>
    </div>
    <div v-bind:style="activeStyle">
      <slot name="item-text"></slot>
    </div>
  </div>
</template>

<script>
export default {
  name: "TabBarItem",
  props: {
    path: String, // 路由路径为必传参数
    activeColor: { // 文字的活跃颜色为可选传参数
      type: String,
      default: function() {
        return "#c45f68"
      }
    }
  },
  computed: {
    isActive() {
      // 通过判断当前活跃路由是否为点击的路由来决定显示活跃图片还是不活跃图片
      return this.$route.path.indexOf(this.path) !== -1 
    },
    activeStyle() {
      // 根据上面的判断来决定是否改变文字的颜色
      return this.isActive ? {color: this.activeColor} : {} 
    }
  },
  methods: {
    itemClick() {
      this.$router.push(this.path)
    }
  }
};
</script>

<style>
  .tab-bar-item {
    flex: 1;
    text-align: center;
    height: 49px;
    font-size: 14px;
  }
  .tab-bar-item img {
    width: 24px;
    height: 24px;
    margin-top: 3px;
    vertical-align: middle;
    margin-bottom: 1px;
  }
</style>

在UseTabBar组件上引用TabBar组件实例

路由相关的映射关系已在路由文件中配置好,这里不再展示

路由路径为必传参数,由于选项活跃时图片颜色和文字颜色会保持一致,推荐也将颜色参数传入

<template>
  <tab-bar>
      <tab-bar-item path="/home" activeColor="#c45f68">
        <img slot="item-icon" src="首页选项不活跃时对应图片的路径" alt="">
        <img slot="item-icon-active" src="首页选项活跃时对应图片的路径" alt="">
        <div slot="item-text">首页</div>
      </tab-bar-item>
      <tab-bar-item path="/classify" activeColor="#c45f68">  
        <img slot="item-icon" src="分类选项不活跃时对应图片的路径" alt="">
        <img slot="item-icon-active" src="分类选项活跃时对应图片的路径" alt="">
        <div slot="item-text">分类</div>
      </tab-bar-item>
      <tab-bar-item path="/shopcart" activeColor="#c45f68">
        <img slot="item-icon" src="购物车选项不活跃时对应图片的路径" alt="">
        <img slot="item-icon-active" src="购物车选项活跃时对应图片的路径" alt="">
        <div slot="item-text">购物车</div>
      </tab-bar-item>
      <tab-bar-item path="/profile" activeColor="#c45f68">
        <img slot="item-icon" src="个人选项不活跃时对应图片的路径" alt="">
        <img slot="item-icon-active" src="个人选项活跃时对应图片的路径" alt="">
        <div slot="item-text">个人</div>
      </tab-bar-item>
    </tab-bar>
</template>

<script>
  import TabBar from "../tabbar/TabBar"
  import TabBarItem from "../tabbar/TabBarItem"

  export default {
    name: "UseTabBar",
    components: {
      TabBar,
      TabBarItem
    }
  }
</script>
讨论数量: 1

可以把图片上传到图床,然后markdown引用

7个月前

慎思笃行