造轮子-tab组件(中)
Posted ories
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了造轮子-tab组件(中)相关的知识,希望对你有一定的参考价值。
1. 如果给一个标签一个class,标签本身又有class,vue是默认会合并的。只有两个属性是这样一个是class,一个是style。这样就比较好改样式。
<g-tabs-head class="red"></g-tabs>
2. 组件的结构以及selected的传递过程,见下图。
- 没有点击的图
- 发生了点击操作的图,两个item兄弟之间是没有关系的,发生了点击操作之后要做下图中的五件事情。
- 亮自己
- 熄兄弟
- 亮pane
- 熄pane
- 触发事件 update:selected -> item2
3. 接下去考虑代码的实现,有两种方案
- 第一种爷爷爸爸儿子之前互相通信
用事件中心EventHub或者叫EventBus发布订阅模式实现,这种简单
4. 下划线开头的属性不要用是私有属性给vue用的,$开头的属性是专门可以用的
5. 在爷爷tabs组件上面加了privide后代都可以用,其他的属性只提供给儿子不提供给孙子,只有provide是任何后代都可以访问的。
// tabs.vue这样就有了eventBus
data(){
return {
eventBus: new Vue()
}
},
provide(){
return {
eventBus:this.eventBus
}
},
created(){
console.log('爷爷的eventBus')
console.log(this.eventBus)
// this.$emit('update:selected','xxx')
}
// tabs-head.vie儿子就有了eventBus,其他组件同理
inject: ['eventBus'],
created(){
console.log('爷爷给爸爸的eventBus')
console.log(this.eventBus)
}
下图橙色字的地方就是provide
6.取函数名字的时候先取一个必须要改的名字,之后再改
created(){
this.eventBus.$on('update:selected',(name)=>{
console.log(name)
})
// 这句话的意思是监听selected被更新了,并且执行一个回调,这里监听的可能是其它的组件
},
methods: {
xxx(){
this.eventBus.$emit('update:selected',this.name)
// 这句话的意思是大声喊出来selected更新了
}
}
7.index.html中,在g-tabs中监听update:selected事件,不会触发yyy,vue的事件是不会冒泡的,在哪里触发就在哪里,但是这个问题不是冒泡问题
// 我们的eventBus是g-tabs生成的new Vue(),而app.js监听的g-tabs,是一个vue组件,
// 也就是vue组件的事件,而不是new Vue()
<g-tabs :selected.sync="selectedTab" @update:selected="yyy"></g-tabs>
methods: {
yyy(data){
console.log('yyy')
console.log(data)
}
}
// 那么组件怎么触发呢
// tabs.vue
created(){
this.$emit('update:selected', '这是 this $emit 出来的数据') // 这样写可以触发外面,这里的this
就是当前组件
this.eventBus.$emit('update:selected', '这是 this event $emit 出来的数据') // 这样写不可以触发外面
}
// app.js
<g-tabs :selected.sync="selectedTab" @update:selected="yyy"></g-tabs>
methods: {
yyy(data){
console.log('yyy')
console.log(data)
}
}
- 总结:事件要看在哪个对象上触发的,你需要知道你触发的事件是在哪个对象上触发的,一个是在this上面,一个是在this的eventBus上面,每个对象都可以触发不同事件。
8. 如果在tabs-header上不会触发
// tabs-head
created(){
this.$emit('update:selected', '这是 tabs-head 抛出来的数据')
// 这样写不可以触发外面是因为vue的事件系统是不会冒泡的,
//如果g-tabs-head标签是一个div那么是可以触发到g-tabs的因为div是可以冒泡的
}
// index.html
<g-tabs :selected.sync="selectedTab" @update:selected="yyy">
<g-tabs-head class="red">
<template slot="actions">
<button>设置</button>
</template>
</g-tabs-head>
</g-tabs>
9.关于Vue的事件要注意点
- 事件是在哪个对象上调用的,在哪个对象上调用就只能在那个对象上监听
- 事件不会冒泡,子标签触发的事件不会自动传到父标签
个人微信,欢迎交流!
以上是关于造轮子-tab组件(中)的主要内容,如果未能解决你的问题,请参考以下文章