上一篇咱们说了完全透明的包裹器 $listeners $attrs
实现了更加便捷的父子组件数据传递
但是大多情况下组件的嵌套不值一层 可能有子组件 孙组件等等 这种情况简易系统的封装一下组件
但是 为使用和调用上层组价的数据和函数 就需要逐层传递
而provide inject就是为了解决这个问题
最上层组件 provide类似于data未保留其独立性 请使用方法传递
<template>
<div id="app">
<ComponentA />
</div>
</template>
<script>
import ComponentA from './Child1.vue'
export default {
name: 'app',
components: {
ComponentA
},
// 最上层组件中返回要传给下级的数据 或者是方法
provide () {
return {
reload: this.alertFun
}
},
methods: {
alertFun () {
alert("!111")
}
}
}
</script>
后代组件 在使用的时候直接用 inject接受对用的函数 然后调用
<template>
<button @click="successHandle">reload</button>
</div>
</template>
<script>
export default {
//引用vue reload方法
inject: ['reload'],
name: 'ComponentC',
mounted () {
},
methods: {
successHandle () {
this.reload()
}
}
}
</script>
提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。
在下面代码中有一个变量是字符串 一个是对象 这个里面跟参数传递一个 以值传递的基础数据类型是无法在底层组件实现数据反向联动的(无法从底层改变数据) 如果需要请封装成对象等非基础数据类型进项传递
<template>
<div id="app">
<ComponentA />
<button @click="alertFun">AAAA</button>
</div>
</template>
<script>
import ComponentA from './Child1.vue'
export default {
name: 'app',
components: {
ComponentA
},
data () {
return {
data1: "111",
data2: {
test: "222"
}
}
},
// 父组件中返回要传给下级的数据
provide () {
return {
reload: this.alertFun,
data1: this.data1,
data2: this.data2
}
},
methods: {
alertFun () {
// this.data1 += "1"
alert(this.data2.test)
}
}
}
</script>
<template>
<div class="component-c">
<button @click="successHandle">reload</button>
</div>
</template>
<script>
export default {
//引用vue reload方法
inject: ['reload', 'data1', 'data2'],
name: 'ComponentC',
methods: {
successHandle () {
alert(this.data2.test)
this.data2.test += "1"
this.reload()
}
}
}
</script>