文章目录
前言
此篇将会叙述如何使用provide/inject进行父子与孙子组件之间的通信传值。
一、概述
这种方式就是Vue中的依赖注入,该方法用于父子组件之间的通信。当然这里所说的父子不一定是真正的父子,也可以是祖孙组件,在层数很深的情况下,可以使用这种方法来进行传值。就不用一层一层的传递了。
参考官网:
https://cn.vuejs.org/v2/api/#provide-inject
provide / inject是Vue提供的两个钩子,和data、methods是同级的。并且provide的书写形式和data一样。
● provide 钩子用来发送数据或方法
● inject钩子用来接收数据或方法
二、使用步骤
1.非响应式
(1)路由里注册父子、孙子组件
// 路由文件——index.js
{
path: '/father',
name: 'father',
component: resolve => require(['@/components/father.vue'], resolve),
children: [
{
path: '/Son',
name:"Son",
component: resolve => require(['@/components/Son.vue'], resolve),
children:[
{
path: '/grandSon',
name:"grandSon",
component: resolve => require(['@/components/grandSon.vue'], resolve),
},
]
},
]
},
(2)父组件中引入儿子组件,使用儿子组件,然后使用provide传送数据
// 父组件——father.vue
<template>
<div id="father">
<h4>{{title}}</h4>
<Son></Son>//2.使用儿子组件
</div>
</template>
<script>
import Son from '../components/Son.vue' //1.引入儿子组件
export default {
components: { Son },
data(){
return{
title:'我是父组件的标题'
}
},
provide(){
return{
title:this.title //3.使用provide传送数据
}
}
}
</script>
<style scoped>
#father{
width: 500px;
height: 500px;
text-align: center;
margin-top:2%;
background-color: bisque;
margin: auto;
/* display: flex; */
}
.inform{
width: 50%;
height: 5%;
}
</style>
(3)儿子组件引入孙子组件,使用孙子组件
// 儿子组件——Son.vue
<template>
<div id="Son">
我现在是子组件
<grand-son></grand-son>//2.使用孙子组件
</div>
</template>
<script>
import grandSon from './grandSon.vue' //1.引入孙子组件
export default {
components: { grandSon },
name:"Son",
data(){
return{
title:'Hey,我现在是儿子'
}
},
}
</script>
<style scoped>
#Son {
width: 300px;
height: 300px;
background-color: cadetblue;
margin: auto;
margin-top: 10px;
}
</style>
(4)孙子组件使用inject接收数据
// 孙子组件——grandSon.vue
<template>
<div id="grandSon">
我现在是孙子组件
<h4>{{title}}</h4>
</div>
</template>
<script>
export default {
name:"grandSon",
data(){
return{
}
},
inject:['title'],//接收来自父组件的数据
}
</script>
<style scoped>
#grandSon {
width: 200px;
height:200px;
background-color:deepskyblue;
margin: auto;
}
</style>
(5)展示
可以看到在层层嵌套下,父组件的数据能够使用provide和inject将数据传给孙子组件。默认情况下,provide/inject 绑定并不是响应式的。
2.响应式
上面说了,默认情况下绑定并不是响应式的。现在我们可以通过传递一个 ref property 或 reactive 对象给 provide 来改变这种行为。
这个响应式我真的花了好长时间才搞明白。
首先是父组件中利用setup函数来渲染模板中title的值,跟着官网的示例来写了代码,但还是报错,说title值未定义。不知道是什么原因。我先暂时没有引入子组件,先希望能够用setup函数渲染出{{title}}。
错误代码如下:
<template>
<div id="father">
<!-- <button @click="setTitle">改变标题</button> -->
<h1>{{title}}</h1>
<!-- <Son></Son> -->
</div>
</template>
<script>
// import Son from '../components/Son.vue' //1.引入儿子组件
export default {
setup() {
const title =ref('我是父组件里面在setup函数里渲染的值')
// 暴露给 template
return {
title
}
}
}
</script>
报错如下:
解决方案:
原因:后来直接删掉了模板{{ title }},先暂时看看有没有进入setup函数,发现根本没有打印出(“我进入setup里面了”)
示例代码:
<template>
<div id="father">
</div>
</template>
<script>
import {ref} from 'vue'
export default {
setup() {
console.log('我进入setup里面了');
}
}
</script>
展示:控制台啥也没有!!!,我一开始是知道setup函数是vue3版本的函数,也用语句vue ——version查看了vue的版本,我认为确实是3版本啊。
后来用语句 “npm list vue”查看了vue的版本,显示是2版本。
原来如此,我在这上面花了整整两天的时间,来实现一个响应式的父子组件传值可太难了。我现在尝试升级vue的版本,让setup给我用起来!!!
这个问题我暂时放弃了,升级vue3还得升级node的版本,各种环境配置。那我就直接看官网写的如何响应式的数据通信。
但是我从中学习到了setup函数。具体知识点可以看到以下的参考链接
参考链接:
vue3版本rovide、inject用法
Provide / inject
Vue3第一篇之ref和reactive详解扩展
Vue3 组合式 API 的基础 —— setup
官网:Setup
总结
有时间我一定会解决这个问题的!