$attrs
1. $attrs的介绍
1.1 正常的父组件向子组件传值:父组件身上通过属性绑定的方式,子组件内部通过props
来接收,但是如果组件嵌套过多,那么就需要在每个父组件身上都进行属性绑定,在内部通过props
来接收,这样就会导致代码混乱,容易导致错误的发生,这个时候我们就需要使用$attrs
1.2 官方定义:包含了父作用域中不作为 prop
被识别 (且获取) 的 attribute
绑定 (class
和 style
除外)。 当一个组件没有声明任何 prop
时,这里会包含所有父作用域的绑定 (class
和 style
除外),并且可以通过 v-bind="$attrs
传入内部组件.
总结:在父组件身上绑定的属性,在子组件中如果没有通过props
的方式获取,那么就会存在子组件的$attrs
身上,就可以通过v-bind="$attrs"
的方式传入下一个子组件,
2. $attrs的使用
html结构
<div id="app">
<one :val="msg" :name="msg1">我是one组件</one>
</div>
js代码
// 第一层组件
Vue.component('one',{
data(){
return {
}
},
template:`
<div>
<slot></slot>
<two v-bind="$attrs">我是two组件</two>
</div>
`,
mounted() {
console.log(this.$attrs);
},
})
// 第二层组件
Vue.component('two',{
data(){
return {
}
},
template:`
<div>
<slot></slot>
<tree v-bind="$attrs">我是tree组件</tree>
</div>
`,
mounted() {
console.log(this.$attrs);
},
})
//第三层组件
Vue.component('tree',{
data(){
return {
}
},
template:`
<div>
<slot></slot>
{{this.$attrs}}
</div>
`,
mounted() {
console.log(this.$attrs);
},
})
new Vue({
el:"#app",
data:{
msg:"多层组件嵌套传值",
msg1: "app"
},
})
代码效果


$listeners
1. $listeners的介绍
1.1 正常的子组件向父组件传值: 通过自定义事件的方式,子组件内部通过$emit
的方式触发自定义事件,父组件通过监听自定义事件来接收,但是这样只适用于子组件向父组件传值,如果是孙子辈以及更深层次的组件,那么就需要在每层上都监听自定义事件,并且触发自定义事件,这样就会导致代码不便于阅读,以及容易出错,那么这个时候我们就可以使用$listeners
1.2 官方定义:包含了父作用域中的 (不含 .native
修饰器的) v-on
事件监听器。它可以通过 v-on="$listeners"
传入内部组件
总结:子组件触发的事件,都会在父组件的$listeners
中,在父组件中就可以通过v-on=$listeners
的方式继续向上一层组件传递
2. $attrs的使用
html结构
<div id="app">
<one @tree="add($event)">我是one组件</one>
{{ val }}
</div>
js代码
Vue.component('one', {
data() {
return {
}
},
props: ['val'],
template: `
<div>
<slot></slot>
<two v-on="$listeners">我是two组件</two>
</div>
`,
mounted() {
console.log(this.$listeners);
},
})
Vue.component('two', {
data() {
return {
}
},
template: `
<div>
<slot></slot>
<tree v-on="$listeners">我是tree组件</tree>
</div>
`,
mounted() {
console.log(this.$listeners);
},
})
Vue.component('tree', {
data() {
return {}
},
template: `
<div>
<slot></slot>
<button @click="add('我是tree组件想根组件传递的值')">点击我想根组件传值</button>
</div>
`,
mounted() {},
methods: {
add(p) {
this.$emit('tree', p)
}
}
})
new Vue({
el: "#app",
data: {
val: "123",
},
methods: {
add(val) {
this.val = val;
}
},
})
初始效果

按钮点击后效果

