目录
前言
父子组件传参可以通过props和emit来实现,但是当组件的层次结构比较深时,props和emit就没什么作用了。vue为了解决这个提出了Provide / Inject,知道这个东西,但是一直没用过,最近碰到了一个问题,踩了一些坑,在这里记录一下
备注:
我安装的是vue3.x,v-model用的是3.x的语法。
2.x和3.x用法一致,我这里是用2.x写的
1.通用知识
基本用法
provide 选项应该是:一个对象或返回一个对象的函数
inject 选项应该是:一个字符串数组,或 一个对象,对象的 [key] 是本地的绑定名
provide 和 inject 绑定并不是可响应的。这是刻意为之的。
代码执行顺序
data->provide->created->mounted
基本代码
主要使用grandpa
和grandson
这两个组件,son
在这里充当一个层级
2.基础用法:
2.1.传个字符串
简单修改一下组件
//grandpa.vue
export default {
components: { Son },
provide:{
grandpaMsg:'哈哈哈'
}
//grandson.vue
<template>
<div>
<el-dialog v-model="visible" title="孙子组件" width="30%" @close="closeDialog">
<div>
信息:{{grandpaMsg}}
</div>
</el-dialog>
</div>
</template>
<script>
export default {
props: {
visible: {
type: Boolean,
default: false,
},
},
inject:['grandpaMsg'],
2.中级用法
传个字符串没啥用,如果要传data
里的一个属性呢?简单修改一下组件
如果要使用data
里的参数,provide需要用returen写法:
//grandpa
components: { Son },
provide(){
return {
grandpaMsg:this.message
}
},
3.高级用法
一开始就说了这个不是响应式,简单看一下
<h3 style="margin-bottom: 20px">爷爷组件</h3>
<el-button type="primary" @click="lookDetail">查看</el-button>
<el-button type="primary" @click="message='abcde'">改变数据</el-button>
那如何变成响应式的呢,再简单改一下
//grandpa
provide(){
return {
grandpaMsg:()=>this.message
}
},
//grandson
<el-dialog v-model="visible" title="孙子组件" width="30%" @close="closeDialog">
<div>
信息:{{grandpaMsg()}}
</div>
</el-dialog>
4.拓展:
你可以直接传一个this
过去,这样孙子组件会获得爷爷组件的实例对象,这种方式也是响应式的
provide(){
return {
grandpaMsg:this
}
},