vue的状态管理的方式:
- 通过vuex进行状态管理
- 通过props的方式向子组件传递状态
- 非父子组件的通信传递 Vue Event Bus ,使用Vue的实例,实现事件的监听和发布,实现组件之间的传递
- inheritAttrs + $attrs + $listeners(父子组件)
现在就第四种方式进行demo演示
当子组件依赖于父组件数据,且需要在子组件中改变状态时,是不能在子组件中直接进行更改的,而是需要事件的方式,子组件通知父组件进行修改,但是当子组件层级过深,props传递会显得臃肿复杂和难以维护,因此,inheritAttrs + $attrs + $listeners应用而生了。
以上是我们遇到的场景,父组件向子组件传递状态,子组件通知父组件,而且所涉及的层级较深。
父组件A:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30<template>
<div class="hello">
<child1 @child1Test='child1Listener'
@child2Test='child2Listener'
:child1Msg=child1Msg
:child2Msg=child2Msg></child1>
</div>
</template>
<script>
import child1 from './child1'
export default {
components: {
child1
},
data () {
return {
child1Msg: 'child1Msg',
child2Msg: 'child2Msg',
}
},
methods: {
child1Listener () {
console.log('child1Listener....')
},
child2Listener () {
console.log('child2Listener...')
}
}
}
</script>
子组件child1:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29<template>
<div>
{{child1Msg}}
<button @click="emit1">child1 event</button>
<child2 v-bind="$attrs" v-on="$listeners"></child2>
</div>
</template>
<script>
import child2 from './child2'
export default {
data () {
return {
msg: 'Welcome child1'
}
},
props: ['child1Msg'],
inheritAttrs: false,
components: {
child2
},
methods: {
emit1 () {
console.log(this.$attrs, this.$listeners)
this.$emit('child1Test');
}
}
}
</script>
子组件child2:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<template>
<div >
{{child2Msg}}
<button @click="emit2">child2 event</button>
</div>
</template>
<script>
export default {
data () {
return {
msg: 'Welcome to child2'
}
},
props:['child2Msg'],
inheritAttrs:false,
methods:{
emit2(){
console.log(this.$attrs, this.$listeners)
this.$emit('child2Test')
}
}
}
</script>
当分别点击child1event和child2event的时候,我们看看控制台的输出:
知识点总结
$attrs
包含了父作用域中不被认为 (且不预期为) props 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 props 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind=”$attrs” 传入内部组件——在创建更高层次的组件时非常有用。$listeners
包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件——在创建更高层次的组件时非常有用。- inheritAttrs
默认情况下父作用域的不被认作 props 的特性绑定 (attribute bindings) 将会“回退”且作为普通的 HTML 特性应用在子组件的根元素上。当撰写包裹一个目标元素或另一个组件的组件时,这可能不会总是符合预期行为。通过设置 inheritAttrs 到 false,这些默认行为将会被去掉。而通过 (同样是 2.4 新增的) 实例属性 $attrs 可以让这些特性生效,且可以通过 v-bind 显性的绑定到非根元素上。
上述特性的使用完全可以降低在不使用Vuex以及事件总线的情况下,组件跨级props以及事件传递的复杂度。