在父子组件传递数据时,通常使用的是 props 和 emit,父传子时,使用的是 props,如果是父组件传孙组件时,就需要先传给子组件,子组件再传给孙组件,如果多个子组件或多个孙组件使用时,就需要传很多次,会很麻烦。

像这种情况,可以使用 provide 和 inject 解决这种问题,不论组件嵌套多深,父组件都可以为所有子组件或孙组件提供数据,父组件使用 provide 提供数据,子组件或孙组件 inject 注入数据。同时兄弟组件之间传值更方便。

一、Vue2 的 provide / inject 使用

provide :是一个对象,里面是属性和值。如:

provide:{
info:"值"
}

如果 provide 需要使用 data 内的数据时,这样写就会报错。访问组件实例 property 时,需要将 provide 转换为返回对象的函数。

provide(){
return{
info: this.msg
}
}

inject :是一个字符串数组。如:

inject: [ 'info' ]

接收上边 provide 提供的 info 数据,也可以是一个对象,该对象包含 from 和 default 属性,from 是可用做的注入内容中搜索用的 key,default 属性是指定默认值。

在 vue2 中 project / inject 应用:

//父组件
export default{
provide:{
info:"提供数据"
}
}
//子组件
export default{
inject:['info'],
mounted(){
console.log("接收数据:", this.info) // 接收数据:提供数据
}
}

provide / inject 类似于消息的订阅和发布。provide 提供或发送数据, inject 接收数据。

二、Vue3 的 provide / inject 使用

在组合式 API 中使用 provide/inject,两个只能在 setup 期间调用,使用之前,必须从 vue 显示导入 provide/inject 方法。

provide 函数接收两个参数:

provide( name,value )

name:定义提供 property 的 name 。

value :property 的值。

使用时:

import { provide } from "vue"
export default {
setup(){
provide('info',"值")
}
}

inject 函数有两个参数:

inject(name,default)

name:接收 provide 提供的属性名。

default:设置默认值,可以不写,是可选参数。

使用时:

import { inject } from "vue"
export default {
setup(){
inject('info',"设置默认值")
}
}

完整实例1:provide/inject实例

//父组件代码
<script>
import { provide } from "vue"
export default {
setup(){
provide('info',"值")
}
}
</script> //子组件 代码
<template>
{{info}}
</template>
<script>
import { inject } from "vue"
export default {
setup(){
const info = inject('info')
return{
info
}
}
}
</script>

三、添加响应性

为了给 provide/inject 添加响应性,使用 ref 或 reactive 。

完整实例2:provide/inject 响应式

//父组件代码
<template>
<div>
info:{{info}}
<InjectCom ></InjectCom>
</div>
</template>
<script>
import InjectCom from "./InjectCom"
import { provide,readonly,ref } from "vue"
export default {
setup(){
let info = ref("今天你学习了吗?")
setTimeout(()=>{
info.value = "不找借口,立马学习"
},2000)
provide('info',info)
return{
info
}
},
components:{
InjectCom
}
}
</script> // InjectCom 子组件代码
<template>
{{info}}
</template>
<script>
import { inject } from "vue"
export default {
setup(){
const info = inject('info')
setTimeout(()=>{
info.value = "更新"
},2000)
return{
info
}
}
}
</script>

上述示例,在父组件或子组件都会修改 info 的值。

provide / inject 类似于消息的订阅和发布,遵循 vue 当中的单项数据流,什么意思呢?就是数据在哪,修改只能在哪,不能在数据传递处修改数据,容易造成状态不可预测。

在订阅组件内修改值的时候,可以被正常修改,如果其他组件也使用该值的时候,状态容易造成混乱,所以需要在源头上规避问题。

readonly 只读函数,使用之前需要引入,如果给变量加上 readonly 属性,则该数据只能读取,无法改变,被修改时会发出警告,但不会改变值。

使用方法:

import { readonly } from "vue"
let info = readonly('只读info值')
setTimout(()=>{
info="更新info" //两秒后更新info的值
},2000)

运行两秒后,浏览器发出警告,提示 info 值不可修改。

所以我们就给provide发射出去的数据,添加一个只读属性,避免发射出去的数据被修改。

完整实例2的 provide 处添加 readonly 。

provide('info', readonly(info))

在子组件修改值的时候,会有一个只读提醒。

修改值的时候,还是需要在 provide 发布数据的组件内修改数据,所以会在组件内添加修改方法,同时也发布出去,在子组件处调用就可以了。如:

//发布
let info = ref("今天你学习了吗?")
const changeInfo = (val)=>{
info.value = val
}
provide('info',readonly(info))
provide('changeInfo',changeInfo) //订阅
const chang = inject('changeInfo')
chang('冲向前端工程师')

完整示例3:修改数据

// 父组件代码
<template>
<div>
info:{{info}}
<InjectCom ></InjectCom>
</div>
</template> <script>
import InjectCom from "./InjectCom"
import { provide,readonly,ref } from "vue"
export default {
setup(){
let info = ref("今天你学习了吗?")
const changeInfo = (val)=>{
info.value = val
}
provide('info',readonly(info))
provide('changeInfo',changeInfo)
return{
info
}
},
components:{
InjectCom
}
}
</script> //InjectCom 子组件代码
<template>
<div>
<button @click="chang('冲向前端工程师')">更新值</button>
</div>
</template>
<script>
import { inject } from "vue"
export default {
setup(){
const info = inject('info')
const chang = inject('changeInfo')
return{
info,
chang
}
}
}
</script>

vue 3 学习笔记 (八)——provide 和 inject 用法及原理的更多相关文章

  1. Vue.js学习笔记(2)vue-router

    vue中vue-router的使用:

  2. Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  3. vue.js 学习笔记3——TypeScript

    目录 vue.js 学习笔记3--TypeScript 工具 基础类型 数组 元组 枚举 字面量 接口 类类型 类类型要素 函数 函数参数 this对象和类型 重载 迭代器 Symbol.iterat ...

  4. python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑

    python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件?当我们点开下载页时, 一般 ...

  5. Go语言学习笔记八: 数组

    Go语言学习笔记八: 数组 数组地球人都知道.所以只说说Go语言的特殊(奇葩)写法. 我一直在想一个人参与了两种语言的设计,但是最后两种语言的语法差异这么大.这是自己否定自己么,为什么不与之前统一一下 ...

  6. Vue.js学习笔记:在元素 和 template 中使用 v-if 指令

    f 指令 语法比较简单,直接上代码: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" " ...

  7. 【opencv学习笔记八】创建TrackBar轨迹条

    createTrackbar这个函数我们以后会经常用到,它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上,使用起来很方便.首先大家要记住,它往往会和一个回调函数配合起来使用.先看下他的函数 ...

  8. go微服务框架kratos学习笔记八 (kratos的依赖注入)

    目录 go微服务框架kratos学习笔记八(kratos的依赖注入) 什么是依赖注入 google wire kratos中的wire Providers injector(注入器) Binding ...

  9. Redis学习笔记八:集群模式

    作者:Grey 原文地址:Redis学习笔记八:集群模式 前面提到的Redis学习笔记七:主从复制和哨兵只能解决Redis的单点压力大和单点故障问题,接下来要讲的Redis Cluster模式,主要是 ...

随机推荐

  1. 2021record

    2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...

  2. Object.create 和 Object.assign

    Object.assign(target, ...source) 1.Object.assign方法只会拷贝源对象自身(不包括原型)的并且可枚举的属性到目标对象,使用源对象的get和目标对象的set, ...

  3. Hive面试题整理(一)

    1.Hive表关联查询,如何解决数据倾斜的问题?(☆☆☆☆☆)   1)倾斜原因:map输出数据按key Hash的分配到reduce中,由于key分布不均匀.业务数据本身的特.建表时考虑不周.等原因 ...

  4. PyCharm永久破解方法,2021最新版本!!!

    1,下载破解补丁(已更新到2021.1版本): 关注微信公众号<程序员的时光>,回复破解补丁即可: 下载补丁文件 jetbrains-agent.jar 和importat.txt文件并将 ...

  5. react 生命周期 个人见解

    初始化/实例期 gitDefaultprops 获取组件的默认props状态 gitInitialstate 类定义方式或是直接在构造函数中挂载state componentWillMount  组件 ...

  6. js_数据类型转换

    转整数----parseInt(string,radix) 1)类似于从左往右匹配数字,直到匹配到非数字结束,并返回匹配到的数字.同parseFloat(). parseInt("123&q ...

  7. Noip模拟45 2021.8.21

    一定别删大括号,检查是;还是, ceil函数里面要写double,否则根本没用!!!!!!! T1 打表 正解:打表 考场上很难真正把柿子理解着推出来 况且想要理解题意就很难,比如我就理解错了 半猜着 ...

  8. 海思 core 电压动态调整

    http://www.eda365.com/forum.php?mod=viewthread&tid=108620&_dsign=5bee4dcb http://www.eda365. ...

  9. 21.6.25 test

    \(NOI\) 模拟赛 \(T1\) 是树+位运算+dp+优化 打了 \(O(n^2)\) 的暴力dp,只拿到了35分,算了一下参赛的,人均65,中位数60.也能看出一些问题,对于一些模糊的猜测应该尝 ...

  10. 调整数组顺序使奇数位于偶数前面 牛客网 剑指Offer

    调整数组顺序使奇数位于偶数前面 牛客网 剑指Offer 题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇 ...