Vue组件通信入门之Provide和Inject机制


Posted in Javascript onDecember 29, 2019

前言

Vue中父组件到子组件的通信主要由子组件的props属性实现。但是在一些情况下,父组件无法直接向子组件的props传值。比如子组件通过父组件的slot进入父组件,父组件根本不知道子组件是谁,更不用说用子组件的props了。这时应该怎么办呢?Vue在2.2.0版本引入了provide与inject,正好适合处理这一情况。

什么是provide与inject

用文档的话说:

provide/inject需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。

这就是说从父组件的provide属性传入一个对象,子组件(或者是孙组件,只要是子级组件)可以用inject属性接收父组件的provide属性。比如

// main.vue
<template>
  <c1 message="hello world">
    <c2></c2>
  </c1>
</template>
 
// c1.vue
<template>
 <div id="c1">
  <slot></slot>
 </div>
</template>
 
<script>
export default {
 props: ['message'],
 provide () {
  return {
   message: this.message
  }
 }
}
</script>
 
// c2.vue
<template>
 <div id="c2">
   {{ message }}
 </div>
</template>
 
<script>
export default {
 inject: ['message']
}
</script>

上面的main组件会被渲染为:

<div id="c1">
 <div id= "c2">hello world</div>
</div>

可以看到,c1组件在不清楚子组件是什么的情况下,将它的props中的message传给了c2组件。在这里c1组件就像是一个数据源一样,为子组件提供数据。但是,c1组件提供的数据仅在c1的子孙组件中可见,因此可以算作是有作用域限定的数据源。

父到子孙组件方向的数据流

父到子孙组件方向是provide/inject机制设计时的数据流方向。我们可能会猜想,在父组件中更改provide的值,子组件会响应式的发生改变。但是注意到文档中话。

提示:provide和inject绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。

这意味着,如果provide的值不是可监听对象时,在父组件中更改provide的值,子组件不会发生任何变化。比如模板仍然为上面那个例子的模板,message的值是一个props属性,不是可监听对象,如果我们在c1的mounted钩子函数里改变message的值。如:

// c1.vue
<script>
export default {
 //...
 mounted () {
  setTimeout( () => {
   this.message = 'Opps, it would not be rendered'
  }, 1000)
 }
}
</script>

子组件不会响应修改后的值。

但是如果provide的值是一个可监听对象呢?请看一下例子:

<script>
// c1.vue
export default {
 data () {
  return {
   message: 'hello world'
  }
 },
 provide () {
  messageData: this.$data
 },
 mounted () {
  setTimeout(() => {
   this.message = 'I can show in c2.'
  }, 10000)
 }
}
</script>
 
// c2.vue
<template>
 <div id="c2">
  {{ messageData.message }}
 </div>
</template>
 
<script>
export default {
 inject: ['messageData']
}
</script>

此时在c1挂载10s后,子组件将会显示I can show in c2。为什么呢?c2中messageData实际上就是c1实例的this.$data。而this.$data上有message的响应式getter与setter。所以c2的视图会被message的dep收集,因此在c1中更新message,c2的视图也会更新。

纵观整个过程,provide/inject机制是非响应式的,即provide与inject之间没有绑定。具体的值是在子组件初始化过程中决定的。

总结

provide/inject提供了一种新的组件间通信的方法。它允许父组件向子孙组件间进行跨层级的数据分发。但是provide/inject是非响应式的,如果要子孙组件根据父组件的值进行改变,provide/inject机制不是一个好的选择。此时可以使用Vuex来管理状态。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
如何实现修改密码时密码框显示保存到cookie的密码
Dec 10 Javascript
Asp.Net alert弹出提示信息的几种方法总结
Jan 29 Javascript
Shell脚本实现Linux系统和进程资源监控
Mar 05 Javascript
javascript实现 百度翻译 可折叠的分享按钮列表
Mar 12 Javascript
jquery输入数字随机抽奖特效的简单实现代码
Jun 10 Javascript
Javascript this 函数深入详解
Dec 13 Javascript
微信小程序-拍照或选择图片并上传文件
Jan 06 Javascript
基于jquery二维码生成插件qrcode
Jan 07 Javascript
JavaScript常用正则函数用法示例
Jan 23 Javascript
正则 js分转元带千分符号详解
Mar 08 Javascript
浅谈Fetch 数据交互方式
Dec 20 Javascript
如何使用原生Js实现随机点名详解
Jan 06 Javascript
JS中数组实现代码(倒序遍历数组,数组连接字符串)
Dec 29 #Javascript
如何基于JavaScript判断图片是否加载完成
Dec 28 #Javascript
Vue页面刷新记住页面状态的实现
Dec 27 #Javascript
uni-app 组件里面获取元素宽高的实现
Dec 27 #Javascript
Vue中axios拦截器如何单独配置token
Dec 27 #Javascript
JavaScript获取当前url路径过程解析
Dec 27 #Javascript
前端开发之便利店收银系统代码
Dec 27 #Javascript
You might like
PHP中使用foreach()遍历二维数组的简单实例
2016/06/13 PHP
PHPstorm快捷键(分享)
2017/07/17 PHP
php的扩展写法总结
2019/05/14 PHP
laravel框架 laravel-admin上传图片到oss的方法
2019/10/13 PHP
TP5框架使用QueryList采集框架爬小说操作示例
2020/03/26 PHP
Javascript匿名函数的一种应用 代码封装
2010/06/27 Javascript
jQuery getJSON()+.ashx 实现分页(改进版)
2013/03/28 Javascript
js中判断对象是否为空的三种实现方法
2013/12/23 Javascript
JavaScript中逗号运算符介绍及使用示例
2015/03/13 Javascript
JS实现灵巧的下拉导航效果代码
2015/08/25 Javascript
JavaScript事件类型中UI事件详解
2016/01/14 Javascript
Bootstrap打造一个左侧折叠菜单的系统模板(一)
2016/05/17 Javascript
js从数组中删除指定值(不是指定位置)的元素实现代码
2016/09/13 Javascript
angularjs实现搜索的关键字在正文中高亮出来
2017/06/13 Javascript
JQuery和html+css实现带小圆点和左右按钮的轮播图实例
2017/07/22 jQuery
Vue状态模式实现窗口停靠功能(灵动、自由, 管理后台Admin界面)
2020/03/06 Javascript
在Windows8上的搭建Python和Django环境
2014/07/03 Python
给Python中的MySQLdb模块添加超时功能的教程
2015/05/05 Python
python相似模块用例
2016/03/04 Python
Python selenium 父子、兄弟、相邻节点定位方式详解
2016/09/15 Python
基于python元祖与字典与集合的粗浅认识
2017/08/23 Python
一篇文章了解Python中常见的序列化操作
2019/06/20 Python
Python验证码截取识别代码实例
2020/05/16 Python
html5使用canvas画空心圆与实心圆
2014/12/15 HTML / CSS
欧缇丽英国官方网站:Caudalie英国
2016/08/17 全球购物
诗普兰迪官方网站:Splendid
2018/09/18 全球购物
UNIX命令速查表
2012/03/10 面试题
职业生涯规划设计步骤
2014/01/12 职场文书
优秀志愿者事迹材料
2014/02/03 职场文书
推广普通话标语
2014/06/27 职场文书
2014年后勤工作总结范文
2014/12/16 职场文书
2015年销售工作总结范文
2015/03/30 职场文书
客服专员岗位职责范本
2015/04/07 职场文书
纪检部部长竞选稿
2015/11/21 职场文书
2019下半年英语教师的教学工作计划(3篇)
2019/09/25 职场文书
十大动画制作软件,Adobe产品上榜两款,第一是行业标准软件
2022/03/18 杂记