vue实现一个tabba组件的封装

封装方式一

1 文件结构

2文件代码

2.1 srcApp.vue

<template>
  <div id="app">
   <!-- <img src="./assets/logo.png">
    <HelloWorld/>-->
    <router-view></router-view>
    <tab-bar >
      <tab-bar-item path="/home" activeColor="#cc1abb" >
        <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-item path="/category" activeColor="deepPink">
        <img slot="item-icon" src="./assets/img/tabbar/category.svg" alt="">
        <img slot="item-icon-active" src="./assets/img/tabbar/category_active.svg" alt="">
        <div slot="item-text">分类</div>
      </tab-bar-item>

      <tab-bar-item path="/shopcart" >
        <img slot="item-icon" src="./assets/img/tabbar/shopcart.svg" alt="">
        <img slot="item-icon-active" src="./assets/img/tabbar/shopcart_active.svg" alt="">
        <div slot="item-text">购物车</div>
      </tab-bar-item>

      <tab-bar-item path="/profile" >
        <img slot="item-icon" src="./assets/img/tabbar/profile.svg" alt="">
        <img slot="item-icon-active" src="./assets/img/tabbar/profile_active.svg" alt="">
        <div slot="item-text">我的</div>
      </tab-bar-item>


    </tab-bar>

  </div>
</template>

<script>
  import TabBar  from "./components/tabbar/TabBar.vue";
  import TabBarItem from "./components/tabbar/TabBarItem.vue";
//import HelloWorld from './components/HelloWorld'

export default {
  name: 'App',
  components: {
    //HelloWorld
    TabBar,
    TabBarItem
  }
}
</script>

<style>
  @import "/assets/css/bass.css";
</style>
View Code

 2.2 srccomponents abbarTabBarItem.vue

<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 :class="{active:isActive}">-->
    <div :style="activeStyle">
      <!--在插槽外面再包装一层 把属性写在包装上 -->
      <slot name="item-text"></slot>
    </div>
  </div>
</template>

<script>
  export default {
    name: "TabBarItem",
    props:{
      path:String,
      activeColor: {
        type:String,
        default:'#42b983'
      }
    },
    data(){
      return{
        //isActive 不要写死 用计算属性动态获取
        //isActive:false
      }
    },
    computed:{
      isActive(){
        //等于-1说明没找到
        return this.$route.path.indexOf(this.path) !== -1
      },
      activeStyle(){
        return this.isActive ?  {color : this.activeColor } : {}
      }
    },
    methods:{
      itemClick(){
        //console.log('itemClick');
        //if(this.$route.path != this.path){
          this.$router.replace(this.path).catch(()=>{})
        //}
      }
    }
  }
</script>

<style scoped>
  .tab-bar-item{
    flex: 1;
    text-align: center;
    height: 49px;
    font-size: 14px;
  }
  .tab-bar-item img{
     24px;
    height: 24px;
    margin-top: 3px;
    vertical-align: middle;
    margin-bottom: 2px;
  }
/*  .active{
    color: @activeColor;//不能这样写
  }*/
</style>
View Code

2.3 srccomponents abbarTabBar.vue

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

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

<style scoped>

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

</style>
View Code

3 完整代码

 链接:https://pan.baidu.com/s/1hgp3W-oPv0SzoW83vqA8Mw
提取码:qp2d

封装方式二 更推荐

1 文件结构

2 。文件代码

2.1 srccomponentsMainTabBar.vue

<template>
  <tab-bar >
    <tab-bar-item path="/home" activeColor="#cc1abb" >
      <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-item path="/category" activeColor="deepPink">
      <img slot="item-icon" src="../../src/assets/img/tabbar/category.svg" alt="">
      <img slot="item-icon-active" src="../../src/assets/img/tabbar/category_active.svg" alt="">
      <div slot="item-text">分类</div>
    </tab-bar-item>

    <tab-bar-item path="/shopcart" >
      <img slot="item-icon" src="../../src/assets/img/tabbar/shopcart.svg" alt="">
      <img slot="item-icon-active" src="../../src/assets/img/tabbar/shopcart_active.svg" alt="">
      <div slot="item-text">购物车</div>
    </tab-bar-item>

    <tab-bar-item path="/profile" >
      <img slot="item-icon" src="../../src/assets/img/tabbar/profile.svg" alt="">
      <img slot="item-icon-active" src="../../src/assets/img/tabbar/profile_active.svg" alt="">
      <div slot="item-text">我的</div>
    </tab-bar-item>


  </tab-bar>
</template>

<script>

  import TabBar  from "@/components/tabbar/TabBar.vue";
  import TabBarItem from "./tabbar/TabBarItem.vue";

  export default {
    name: "MainTabBar",

    components: {
      //HelloWorld
      TabBar,
      TabBarItem
    }
  }
</script>

<style scoped>

</style>
View Code

2.2 buildwebpack.base.conf.js

  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      '@': resolve('src'),
      'assets': resolve('src/assets'),
      'components':resolve('src/components'),
      'views':resolve('src/views')
    }
  },

2.3 srcApp.vue

<template>
  <div id="app">
   <!-- <img src="./assets/logo.png">
    <HelloWorld/>-->
    <router-view></router-view>
    <main-tab-bar></main-tab-bar>

  </div>
</template>

<script>

//import HelloWorld from './components/HelloWorld'
import MainTabBar from "./components/MainTabBar";
export default {
  name: 'App',
  components: {
    //HelloWorld
    // TabBar,
    // TabBarItem
    MainTabBar
  }
}
</script>

<style>
  @import "/assets/css/bass.css";
</style>
View Code

3 完整代码

链接:https://pan.baidu.com/s/1Sq1YusR8hq19Qni-OnXjlw
提取码:sr5p

原文地址:https://www.cnblogs.com/polax/p/13190937.html