作用
现在的需求是想要实现父孙之间的传值,我们能够想到的哪几种方式了?
-
我们使用VueX来进行数据管理,但是如果项目中多个组件共享状态比较少,项目比较小,并且全局状态比较少,那使用VueX来实现该功能,并没有发挥出VueX的威力。
-
使用B来做中转站,当A组件需要把信息传给C组件时,B接受A组件的信息,然后利用属性传给C组件,这是一种解决方案,但是如果嵌套的组件过多,会导致代码繁琐,代码维护比较困难;如果C中状态的改变需要传递给A, 使用事件系统一级级往上传递
-
自定义一个Vue 中央数据总线,这个情况适合碰到组件跨级传递消息,但是使用VueX感觉又有点浪费的项目中,但是缺点是,碰到多人合作时,代码的维护性较低,代码可读性低
在vue2.4中,为了解决该需求,引入了listeners , 新增了inheritAttrs 选项。 在版本2.4以前,默认情况下父作用域的不被认作props的属性将会作为普通的HTML特性应用在子组件的根元素上。
如下列的例子
- 父组件
<template>
<div>
<child-dom
:foo="foo"
:coo="foo"
>
</child-dom>
</div>
</template>
<script>
import childDom from "./ChildDom.vue";
export default {
data() {
return {
foo:"Hello, world",
coo:"Hello,rui"
}
},
components:{childDom},
}
</script>
- 子组件
<template>
<div>
<p>foo:{{foo}}</p>
</div>
</template>
<script>
export default {
name:'child-dom'
props:["foo"]
}
</script>
子组件中没有接受coo所以coo就作为普通的HTML的一个属性
$attrs的用法
实现父先孙传值的需求
- 父组件
给子组件关联数据,子组件如果不用props接收,那么这些数据就作为普通的HTML特性应用在子组件的根元素上
<template>
<div>
<p>父组件</p>
<Child :foo="foo" :obj="obj"></Child>
</div>
</template>
<script>
import Child from "./B1.vue";
export default {
components: {
Child,
},
data() {
return {
foo: "foo",
obj: {
name: "wangjinyu",
like: "watch tv",
},
};
},
};
</script>
<style>
</style>
- 儿子组件
作为父组件和孙子组件的传递中介,在儿子组件中给孙子组件添加v-bind="$attrs",这样孙子组件才能接收到数据
<template>
<div class='child-view'>
<p>儿子组件</p>
<GrandChild v-bind="$attrs"></GrandChild>
</div>
</template>
<script>
import GrandChild from './GrandChild.vue'
export default {
// 继承所有父组件的内容,把传值作为html的属性,显示在dom元素上面
inheritAttrs: true,
components: { GrandChild },
data() {
return {
}
}
}
</script>
- 孙子组件
在孙子组件中一定要使用props接收从父组件传递过来的数据
<template>
<div>
<p>孙组件</p>
<div>{{foo}}</div>
<div>{{obj.name}}</div>
</div>
</template>
<script>
export default {
props: {
foo: {
type: String,
default: "",
},
obj: {
type: Object,
default: () => {},
},
},
// 不想继承所有父组件的内容,同时也不在组件根元素dom上显示属性
inheritAttrs: false,
};
</script>
<style>
</style>
- 结果展示