最近刚好有个需求,移动端tab栏,但是数据又在一个接口中,想用props传参,个人觉得有点麻烦,于是研究一下,发现了一个好用的属性,provide. 附上官网地址:provide/inject
简介
provide 属性作用就是通过声明provide(对象|对象的函数),子组件调用了inject就可以注入provider中的数据,个人觉得比prop属性更加灵活
实践
//父组件代码
<template>
<div>
<div style="color:green">父组件:{{msg}}</div>
<div style="color:green">父组件:{{grandMsg}}</div>
<div>
<injectChild1></injectChild1>
</div>
<div>
<injectChild2></injectChild2>
</div>
<el-button type="primary" @click="changegrandMsg">点击修改msg</el-button>
</div>
</template>
<script>
export default {
name: "prvideusageindex",
data() {
return {
msg: "我是父组件数据",
grandMsg: "直接传到孙子组件"
};
},
provide() {
return {
demo: this.msg,
grandMsg:() => this.grandMsg
};
},
components: {
injectChild1: () => import("./provideugecomponent/injectChild1"),
injectChild2: () => import("./provideugecomponent/injectChild2")
},
methods: {
changegrandMsg() {
this.grandMsg = "传到孙子组件值被修改";
}
}
};
</script>
//子组件1代码
<template>
<div>
子组件1:{{demo}}
</div>
</template>
<script>
export default {
name: "injectChild1",
data() {
return {};
},
inject: ["demo"]
};
</script>
//子组件2代码
<template>
<div>
子组件2:{{demo}}
<injectGrand></injectGrand>
</div>
</template>
<script>
export default {
name: "injectChild2",
data() {
return {};
},
inject: ["demo"],
components: {
injectGrand: () => import("./grandcom/injectgrand"),
},
};
</script>
<style scoped>
//孙子组件代码
<template>
<div>子组件2的子组件:{{changeGrandMsg}}</div>
</template>
<script>
export default {
name: "injectChild2",
data() {
return {};
},
inject: ["grandMsg"],
computed: {
changeGrandMsg() {
return this.grandMsg();
}
}
};
</script>
效果图
点击按钮之前
点击按钮之后
provide/inject绑定并不是可响应的。所以需要自己处理。如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。
总结
1.provide/inject 父组件声明provide,应该是一个对象或返回一个对象的函数,子组件中通过inject注入,即可拿到父组件数据
2.provide/inject可以轻松实现跨级访问祖先组件的数据
3.provide/inject传递数据不是响应式的,需要自己处理,上述我也简单测试了效果,在父组件中传入一个方法的返回值,在子组件接收的时候computed监听一下,即可实现响应式改变
个人拙见,如果有错误或好的想法,欢迎指出!希望对需要的朋友有所帮助!