之前做移动端的项目一般会选用Mint-ui或者是Vux框架,不得不说这两款都是非常棒非常好用的UI框架,能给开发工作节省很多时间。
在Mint-ui里关于tabbar的使用,有如下的Demo:
<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即可。
引申出来这么个问题:
- 那么在父组件中如何区分按下的是哪个子组件呢?
通过判断children的_uid可以区分出究竟是哪个子组件
- 子组件如何将自身的_uid抛给父组件呢?
调用$parent.$emit('input', _uid),直接这样调用,会修改v-model绑定value值。
v-model="selected" 可以看成是 v-bind:value="selected" v-on:input="selected = $event.target.value" 的语法糖
有了这几步分析,然后自己写了一份简单的tabbar组件
tabbar.vue
<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.vue
<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的绑定依赖:
<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服务的,所以不需要关心太过于耦合,考虑复用性等问题。
如思考的不到位请各位大神能给予一些指导意见。
Github: github.com/lyh2668
AuthBy: lyh2668