在Vue项目的开发中,我们经常会遇到组件嵌套层级过深的问题,常用的两种方式,链式调用以及emit触发,在多组件嵌套中都有一定的不足,例如链式调用记得的降低了组件的可复用性,因为组件后面所处的层级是可变的,另一边emit触发方法的传递则需要传递的层数过多,代码过于臃肿,不易维护,所以对于多组件嵌套来说,我们建议通过provide / inject进行方法以及属性的传递。
一、通过provide / inject实现组件的传参
废话不多说,直接上代码
结构如下,共三级,父子孙三层组件
父组件代码:
<template>
<div>我是父组件,我的num是{{ num }}。<button @click="changnum">更改num的值</button>
<son></son>
</div>
</template>
<script>
import son from './son.vue'
export default {
components:{
son
},
data(){
return{
num:0
}
},
provide(){
return {
num:()=>this.num,
changnum:this.changnum
}
},
methods:{
changnum(){
this.num++
}
}
}
</script>
<style>
</style>
子组件代码:
<template>
<div>我是平平无奇的子组件,有了provide / inject我好轻松
<sun></sun>
</div>
</template>
<script>
import sun from "./sun.vue"
export default {
components:{
sun
}
}
</script>
<style>
</style>
孙组件代码:
<template>
<div>我是孙组件,我获取到的父组件的父组件的num为{{ num() }},<button @click="changnum">更改父组件的父组件的值</button></div>
</template>
<script>
export default {
inject:['num','changnum'],
};
</script>
<style>
</style>
二、简要补充说明
传递响应式的数据,需要传递一个方法过去,去触发方法,建立关联。不然得到的是初始data里面的值,不是响应式的。
inject可以设置默认值,跟props类似
provide / inject需要搭配使用,当父组件没有传递,子组件接收也会报错。