$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;
}
},
})
初始效果
按钮点击后效果