vue2.0 之 douban (二)创建自定义组件tabbar

1.大体布局

这个组件分为两部分:第一个是组件的外层容器,第二个是组件的子容器item,子组件里面又分为图片和文字组合。子组件有2个状态,一个默认灰色的状态,一个选中状态,我们来实现一下这个组件的布局

Index.vue

<template>
  <div class="m-tabbar">
    <a class="m-tabbar-item is-active">
      <span class="m-tabbar-item-icon">
        <img src="../assets/images/ic_tab_home_normal.png" alt="">
      </span>
      <span class="m-tabbar-item-text">
        首页
      </span>
    </a>
    <a class="m-tabbar-item">
      <span class="m-tabbar-item-icon">
        <img src="../assets/images/ic_tab_subject_normal.png" alt="">
      </span>
      <span class="m-tabbar-item-text">
        书影音
      </span>
    </a>
    <a class="m-tabbar-item">
      <span class="m-tabbar-item-icon">
        <img src="../assets/images/ic_tab_status_normal.png" alt="">
      </span>
      <span class="m-tabbar-item-text">
        广播
      </span>
    </a>
    <a class="m-tabbar-item">
      <span class="m-tabbar-item-icon">
        <img src="../assets/images/ic_tab_group_normal.png" alt="">
      </span>
      <span class="m-tabbar-item-text">
        小组
      </span>
    </a>
    <a class="m-tabbar-item">
      <span class="m-tabbar-item-icon">
        <img src="../assets/images/ic_tab_profile_normal.png" alt="">
      </span>
      <span class="m-tabbar-item-text">
        我的
      </span>
    </a>
  </div>
</template>

<script>
export default {

}
</script>

<style lang="less">
.m-tabbar{
    display: flex;
    flex-direction: row;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
    height: 50px;
    background: #fff;
    border-top: 1px solid #e4e4e4;

    .m-tabbar-item{
      flex: 1;
      text-align: center;
      .m-tabbar-item-icon{
          display: block;
          padding-top: 2px;
          img{
              width: 28px;
              height: 28px;
          }
      }
      .m-tabbar-item-text{
          display: block;
          font-size: 10px;
          color:#949494;
      }
      &.is-active{
          .m-tabbar-item-text{
              color: #42bd56;
          }
      }
  }
}
</style>

效果图:

 

2.组件化

先在components文件夹下面,新建两个组件,通过这两个组件来组合实现我们底部的tab组件:

(一)一个是tabbar-item.vue,实现子组件的item项

tabbar-item.vue

<template>
  <a class="m-tabbar-item" >
    <span class="m-tabbar-item-icon"><slot name="icon-normal"></slot></span>
    <span class="m-tabbar-item-text"><slot></slot></span>
  </a>
</template>

<style lang="less">
.m-tabbar-item{
  flex: 1;
  text-align: center;
  .m-tabbar-item-icon{
    display: block;
    padding-top: 2px;
    img{
      width: 28px;
      height: 28px;
    }

  }
  .m-tabbar-item-text{
    display: block;
    font-size: 10px;
    color:#949494;
  }
  &.is-active{
    .m-tabbar-item-text{
      color: #42bd56;
    }
  }
}
</style>

 

(二)一个是tabbar.vue,实现tab的外层容器

 tabbar.vue

<template>
  <div class="m-tabbar">
    <slot></slot>
  </div>
</template>
<style lang="less">
.m-tabbar{
  display: flex;
  flex-direction: row;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100%;
  overflow: hidden;
  height: 50px;
  background: #fff;
  border-top: 1px solid #e4e4e4;
}
</style>

 

在Index.vue中组合这两个组件,实现tab组件效果

Index.vue

<template>
  <div>
    <m-tabbar>
      <m-tabbar-item id='tab1'>
        <img src="../assets/images/ic_tab_home_normal.png" alt="" slot="icon-normal">
        首页
      </m-tabbar-item>
      <m-tabbar-item id='tab2'>
        <img src="../assets/images/ic_tab_subject_normal.png" alt="" slot="icon-normal">
        书影音
      </m-tabbar-item>
      <m-tabbar-item id='tab3'>
        <img src="../assets/images/ic_tab_status_normal.png" alt="" slot="icon-normal">
        广播
      </m-tabbar-item>
      <m-tabbar-item id='tab4'>
        <img src="../assets/images/ic_tab_group_normal.png" alt="" slot="icon-normal">
        小组
      </m-tabbar-item>
       <m-tabbar-item id='tab5'>
        <img src="../assets/images/ic_tab_profile_normal.png" alt="" slot="icon-normal">
        我的
      </m-tabbar-item>
    </m-tabbar>
  </div>
</template>

<script>
  import mTabbar from '../components/tabbar'
  import mTabbarItem from '../components/tabbar-item'
  export default {
    name: 'index',
    components: {
      mTabbar,
      mTabbarItem
    }
  }
</script>

 

效果图:

 

3.实现点击切换的效果

步骤一:

先给Index.vue里面的tab组件加上v-model 来进行数据双向绑定,通过select来达到选择item,在item里面再添加一个选中的active图片

Index.vue

<template>
  <div>
    <m-tabbar v-model="select">
      <m-tabbar-item id='tab1'>
        <img src="../assets/images/ic_tab_home_normal.png" alt="" slot="icon-normal">
        <img src="../assets/images/ic_tab_home_active.png" alt="" slot="icon-active">
        首页
      </m-tabbar-item>
      <m-tabbar-item id='tab2'>
        <img src="../assets/images/ic_tab_subject_normal.png" alt="" slot="icon-normal">
        <img src="../assets/images/ic_tab_subject_active.png" alt="" slot="icon-active">
        书影音
      </m-tabbar-item>
      <m-tabbar-item id='tab3'>
        <img src="../assets/images/ic_tab_status_normal.png" alt="" slot="icon-normal">
        <img src="../assets/images/ic_tab_status_active.png" alt="" slot="icon-active">
        广播
      </m-tabbar-item>
      <m-tabbar-item id='tab4'>
        <img src="../assets/images/ic_tab_group_normal.png" alt="" slot="icon-normal">
        <img src="../assets/images/ic_tab_group_active.png" alt="" slot="icon-active">
        小组
      </m-tabbar-item>
      <m-tabbar-item id='tab5'>
        <img src="../assets/images/ic_tab_profile_normal.png" alt="" slot="icon-normal">
        <img src="../assets/images/ic_tab_profile_active.png" alt="" slot="icon-active">
        我的
      </m-tabbar-item>
    </m-tabbar>
  </div>
</template>

<script>
  import mTabbar from '../components/tabbar'
  import mTabbarItem from '../components/tabbar-item'
  export default {
    name: 'index',
    components: {
      mTabbar,
      mTabbarItem
    },
    data() {
      return {
        select:"tab1"
      }
    }
  }
</script>

  

步骤二:

tabbar.vue里面通过props来传递数据vaule

tabbar.vue

<template>
  <div class="m-tabbar">
    <slot></slot>
  </div>
</template>
<script>
  import mTabbarItem from './tabbar-item';
  export default {
    props: ['value']
  }
</script>
<style lang="less">
.m-tabbar{
  display: flex;
  flex-direction: row;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100%;
  overflow: hidden;
  height: 50px;
  background: #fff;
  border-top: 1px solid #e4e4e4;
}
</style>

 

步骤三:

tabbar-item.vue组件:根据父组件的value和当前组件的id判断是否为选中状态,通过 $parent.$emit('input',id) - 触发父组件的自定义事件,添加选中的图片,根据isActive来显示隐藏

tabbar-item.vue

<template>
    <a class="m-tabbar-item" :class="{'is-active':isActive}" @click="$parent.$emit('input',id)">
        <span class="m-tabbar-item-icon" v-show="!isActive"><slot name="icon-normal"></slot></span>
        <span class="m-tabbar-item-icon" v-show="isActive"><slot name="icon-active"></slot></span>
        <span class="m-tabbar-item-text"><slot></slot></span>
    </a>
</template>

<script>
    export default{
        props: ['id'],
        computed: {
            isActive(){
               if(this.$parent.value===this.id){
                   return true;
               }
            }
        }
    }
</script>

<style lang="less">
.m-tabbar-item{
    flex: 1;
    text-align: center;
    .m-tabbar-item-icon{
        display: block;
        padding-top: 2px;
        img{
            width: 28px;
            height: 28px;
        }

    }
    .m-tabbar-item-text{
        display: block;
        font-size: 10px;
        color:#949494;
    }
    &.is-active{
        .m-tabbar-item-text{
            color: #42bd56;
        }
    }
}
</style>

 

效果图:

.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值