vue当中设计Tabbar插件时的思考

以前作移动端的项目通常会选用Mint-ui或者是Vux框架,不得不说这两款都是很是棒很是好用的UI框架,能给开发工做节省不少时间。css

在Mint-ui里关于tabbar的使用,有以下的Demo:vue

<mt-tabbar v-model="selected">
  <mt-tab-item id="订单">
    <img slot="icon" src="http://placehold.it/100x100">
    <span slot="label">订单</span>
  </mt-tab-item>
</mt-tabbar>
复制代码

使用了之后就想...为何必定要对每一个mt-tab-item指定一个id呢?对于tabbar来讲,我并不须要关心我按下的对象id是多少,而须要关心的是按下哪一个tabbar-item便可。 引伸出来这么个问题:git

  1. 那么在父组件中如何区分按下的是哪一个子组件呢?

经过判断children的_uid能够区分出到底是哪一个子组件github

  1. 子组件如何将自身的_uid抛给父组件呢?

调用$parent.$emit('input', _uid),直接这样调用,会修改v-model绑定value值。数组

v-model="selected" 能够当作是 v-bind:value="selected" v-on:input="selected = $event.target.value" 的语法糖bash

有了这几步分析,而后本身写了一份简单的tabbar组件框架

tabbar.vuesvg

<template>
  <div class="l-tabbar">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'LTabbar',
  component: 'LTabbar',
  props: {
    value: {}
  },
  methods: {
    index (id) {
      for (let i = 0; i < this.$children.length; ++i) {
        if (this.$children[i]._uid === id) {
          return i
        }
      }
      return -1
    }
  }
}
</script>

<style lang="scss">
.l-tabbar {
  position: absolute;
  width: 100%;
  height: auto;
  bottom: 0;
  left: 0;
  right: 0;
  background: white;
  display: flex;
  justify-content: space-around;
}
</style>
复制代码

tabbarItem.vueflex

<template>
  <div class="tabbar-item"
    @click="$parent.$emit('input', id)"
    :class="{ 'is-selected': $parent.value === id }">
    <div class="item-icon">
      <slot name="icon"></slot>
    </div>
    <div class="item-text">
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
  name: 'LTabbarItem',
  component: 'LTabbarItem',
  data () {
    return {
      id: this.$parent.index(this._uid)
    }
  }
}
</script>

<style lang="scss">
@import '../../common/style/var.scss';

.tabbar-item {
  text-align: center;
  margin: 5px auto;
  width: 100%;
  &.is-selected {
    color: $default-color;
  }
  .item-text {
    font-size: 12px;
  }
}
</style>
复制代码

这样写完之后,使用的时候会比mint-ui的组件更简化,能够取消对id的绑定依赖:ui

<l-tabbar v-model="selected">
  <l-tabbar-item v-for="(item, index) in tabItems" :key="index">
    <svg slot="icon" :class="icon" aria-hidden="true">
      <use :xlink:href="`#${item.icon}`"></use>
    </svg>
    <span>{{ item.title }}</span>
  </l-tabbar-item>
</l-tabbar>
复制代码

虽然到这一步改造是完成了,可是却总以为有些问题。 那么在子组件里面调用父组件的methods是否合适? 可是后来想一想tabbar-item仅仅是为tabbar服务的,因此不须要关心太过于耦合,考虑复用性等问题。 如思考的不到位请各位大神能给予一些指导意见。

再次改进(12/03)

parent:
删除methods index
child:
data () {
  return {
    id: this.$parent.$children.length - 1
  }
}
复制代码

仔细分析发现,其实每次插入一个item的时候取到其在$parent.$children的位置便可,因为是经过push的方式放入$children数组的,因此我只须要取到最后一个item便是它的index

Github: github.com/lyh2668 AuthBy: lyh2668

相关文章
相关标签/搜索