此次呢就帶你們封裝一個tabbar。html
咱們此次封裝的tabbar 須要有那些功能???vue
我們開發的時候爲了方便其實能夠直接在App.vue裏寫代碼,而後在拷貝到對應的文件裏。(cv 沒法避免了😱)git
先新建幾個文件,須要用到。 github
把color-ui小程序項目裏的操做條拷貝過來,並修改爲我們可使用的。view ===> div
text ===> p
<div class="cu-bar foot tabbar bg-black">
<div class="action text-orange">
<p class="icon-homefill"></p> 首頁
</div>
<div class="action text-gray">
<p class="icon-similar"></p> 分類
</div>
<div class="action text-gray">
<p class="icon-recharge"></p>
積分
</div>
<div class="action text-gray">
<div class="icon-cart">
<p class="cu-tag badge">99</p>
</div>
購物車
</div>
<div class="action text-gray">
<div class="icon-my">
<p class="cu-tag badge"></p>
</div>
個人
</div>
</div>
複製代碼
漂亮的一批批的,咱們已經完成了一丟丟。
這一步我要把 Tabbar 和 TabbarItem 分割開。小程序
export default {
name: 'Tabbar',
render(h) {
return (
<div class="cu-bar foot tabbar bg-black">{this.$slots.default}</div>
);
}
}
// 有同窗可能注意到了this.$slots.default
// 下文有講解,莫慌!
複製代碼
import Tabbar from './src/main';
Tabbar.install = function(Vue) {
Vue.component(Tabbar.name, Tabbar);
};
export default Tabbar;
複製代碼
import Tabbar from '../packages/tabbar';
Vue.use(Tabbar);
複製代碼
<Tabbar></Tabbar>
複製代碼
emmmmmmmmm……好像有點翻車……球的麻袋……數組
我們繼續如法炮製 TabberItembash
Tips:
在tabbar-item/src/main.js 中咱們只須要放一個 TabbarItem.
export default {
name: 'TabbarItem',
render(h) {
return (
<div class="action text-gray">
<div class="icon-my">
<p class="cu-tag badge"></p>
</div>
個人
</div>
);
}
}
爲啥?
由於每個TabbarItem 都是要傳入不一樣icon和文字的撒!
複製代碼
哎,成了?好像還有點問題……icon都是寫死的,文字也是寫死的,最重要的是切換效果呢?跳轉呢?????ide
一個個來莫着急老鐵!import Icon from '../../icon'; // 上一篇文章我們封裝icon
export default {
name: 'TabbarItem',
props: {
icon: String
},
components: {
Icon
},
render(h) {
return (
<div class="action text-gray">
<Icon icon={icon}></Icon> // 這裏呢直接調用……
個人
</div>
);
}
}
複製代碼
App.vue
<Tabbar>
<TabbarItem icon="icon-homefill">首頁</TabbarItem>
<TabbarItem icon="icon-similar">分類</TabbarItem>
<TabbarItem icon="icon-cart">購物車</TabbarItem>
<TabbarItem icon="icon-my">個人</TabbarItem>
</Tabbar>
複製代碼
能夠看到我們已經能夠自定義icon和標題文字了……
這裏我直接上代碼,慢慢給你們講解。ui
/packages/tabbar/src/main.js
export default {
name: 'Tabbar',
data() {
return {
items: [] // 這裏放一個數組用於存放 TabbarItem
};
},
props: {
value: Number, // 確定會有人納悶這個是啥??? 下文解釋1
fixed: Boolean,
activeColor: String, // 請看下文解釋2
bgColor: {
type: String,
default: 'bg-black'
}
},
methods: {
setActiveItem() { // 判斷 item.active 是否爲true
this.items.forEach((item, index) => {
item.active = index === this.value;
});
},
onChange(active) {
if (active !== this.value) {
this.$emit('input', active); // 通知App.vue 更改data值。
this.$emit('change', active); // 解釋3
}
}
},
watch: {
items() {
this.setActiveItem();
},
value() {
this.setActiveItem();
}
},
components: {
},
render(h) {
const { fixed, bgColor, $slots } = this;
const classed = [
{
'foot': fixed,
},
bgColor,
'cu-bar tabbar'
]
return (
<div class={classed}>
{$slots.default}
</div>
);
}
}
複製代碼
export default {
name: 'TabbarItem',
props: {
icon: String
},
data() {
return {
active: false
};
},
beforeCreate() { // Tabbar組件 = this.$parent,是的之後你能夠經過this.$parent 直接獲取父組件.
this.$parent.items.push(this);
},
destroyed() {
this.$parent.items.splice(this.$parent.items.indexOf(this), 1);
},
methods: {
onClick(event) { // Big Boss…… 不用過多解釋了吧……
this.$parent.onChange(this.$parent.items.indexOf(this));
}
},
render(h) {
const { icon, $slots, active } = this;
const avtive = active ? this.$parent.activeColor + ' action' : 'action text-gray';
return (
<div onClick={this.onClick} class={avtive}>
<div class={icon}>
</div>
<span>{$slots.default}</span>
</div>
);
}
}
複製代碼
App.vue
<Tabbar v-model="data" fixed :activeColor="'text-green'" :bgColor="'bg-black'">
<TabbarItem icon="icon-homefill">首頁</TabbarItem>
<TabbarItem icon="icon-similar">分類</TabbarItem>
<TabbarItem icon="icon-cart">購物車</TabbarItem>
<TabbarItem icon="icon-my">個人</TabbarItem>
</Tabbar>
複製代碼
還記得我上一篇文章說過Tabbar 是一個父容器麼?
那麼咱們能夠把一些公用的屬性放到父容器上面……
在子組件須要使用的時候 能夠經過this.$parent 來獲取父容器上的屬性方法等等……
你也能夠設置一個 默認不選中的顏色喲!
若是你想的話你也能夠在每一個TabbarItem 上面加……
路由這個……就留到下一章把……畢竟有些人基礎不是那麼好。一會兒寫太多內容不太好!
源碼的話……