作为一个前端开发,vue这个框架的使用是必不可少的。组件通讯是必不可少的,比如:子传父、父传子、非父子传参等等。
一般复杂一点的项目都会涉及到多层传参,刚使用vue不久的我是通过props一层一层往下传的,这样有个问题就是代码量大,可维护性不强。vuex
也可以解决这个问题,但是感觉有点杀鸡用牛刀的感觉,大材小用。后面vue出了一个方法$attrs
专门解决这个问题
$attr
:包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
下面举例子将值A->B->C,从A传到C(父组件传值给孙子组件)
1、父组件
这时候我们传了两个参数title和type
<template>
<div>
<div class="father" @click="father">我是父组件,点击传值给孙子组件</div>
<child :title="title" :type="type" />
</div>
</template>
<script>
import child from "./components/child";
export default {
components: {
child
},
data() {
return {
title: "",
type: ""
};
},
methods: {
father() {
this.title = "========> 父组件传过来的title";
this.type = "========> 父组件传过来的type";
}
}
};
</script>
2、子组件
儿子组件(child.vue),中间层,作为父组件和孙子组件的传递中介,在儿子组件中给孙子组件添加v-bind="$attrs",这样孙子组件才能接收到数据,我们在子组件用props接收了一个title参数,那么我们在孙子组件就只能获取到type这个参数了
<template>
<div>
<div class="child">
<div>我是儿子组件{{child_title}}</div>
</div>
<grandson v-bind="$attrs" />
</div>
</template>
<script>
import grandson from "./grandson";
export default {
components: {
grandson
},
props: {
title: {
type: String,
default: ""
}
},
watch: {
$attrs() {
console.log(this.$attrs, "attrs");
},
title() {
this.child_title = this.title;
console.log(this.title, "========》 子组件");
}
},
data() {
return {
child_title: "",
childType: ""
};
}
};
</script>
3、孙子组件
这时候我们在watch里同时打印了title和type两个参数,然而只有type是存在的
<template>
<div>
<div class="grandson">我是孙子组件{{title}}{{type}}</div>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: ""
},
type: {
type: String,
default: ""
}
},
watch: {
title() {
console.log(this.title, "this.title =====> 孙子组件");
},
type() {
console.log(this.type, "this.type =====> 孙子组件");
}
},
data() {
return {};
}
};
</script>
总结:当我们涉及到多层传参的时候,父组件传出去的值,中间的组件不用通过props接收,但是要在子组件身上通过v-bind="$attrs"
,这样最下层的组件才能拿到最外层组件传过来的值