以前作移動端的項目通常會選用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
經過判斷children的_uid能夠區分出到底是哪一個子組件github
調用$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服務的,因此不須要關心太過於耦合,考慮複用性等問題。 如思考的不到位請各位大神能給予一些指導意見。
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