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 相关文章推荐
js之事件冒泡和事件捕获详细介绍
Oct 28 Javascript
jQuery插件expander实现图片翻转特效
May 21 Javascript
JavaScript实现的简单拖拽效果
Jun 01 Javascript
深入理解JavaScript中的对象
Jun 04 Javascript
解决jquery无法找到其他父级子集问题的方法
May 10 Javascript
javascirpt实现2个iframe之间传值的方法
Jun 30 Javascript
浅谈js中的引用和复制(传值和传址)
Sep 18 Javascript
vue实现ToDoList简单实例
Feb 07 Javascript
vue-cli与webpack处理静态资源的方法及webpack打包的坑
May 15 Javascript
如何用Node写页面爬虫的工具集
Oct 26 Javascript
JavaScript原型对象原理与应用分析
Dec 27 Javascript
解决vue props传Array/Object类型值,子组件报错的情况
Nov 07 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
基于文本的留言簿
2006/10/09 PHP
php创建基本身份认证站点的方法详解
2013/06/08 PHP
PHP和JavaScrip分别获取关联数组的键值示例代码
2013/09/16 PHP
php使用parse_url和parse_str解析URL
2015/02/22 PHP
浅谈COOKIE和SESSION区别
2015/07/19 PHP
FF IE浏览器修改标签透明度的方法
2014/01/27 Javascript
9款2014最热门jQuery实用特效推荐
2014/12/07 Javascript
jQuery实现表格行上下移动和置顶效果
2015/06/05 Javascript
理解Javascript的动态语言特性
2015/06/17 Javascript
javascript实现checkbox复选框实例代码
2016/01/10 Javascript
浅析JavaScript中的对象类型Object
2016/05/26 Javascript
javascript 动态脚本添加的简单方法
2016/10/11 Javascript
jquery实现瀑布流效果 jquery下拉加载新数据
2016/12/12 Javascript
jQuery中table数据的值拷贝和拆分
2017/03/19 Javascript
underscore之Chaining_动力节点Java学院整理
2017/07/10 Javascript
openlayers实现地图测距测面
2020/09/25 Javascript
Python3.X 线程中信号量的使用方法示例
2017/07/24 Python
Python实现图片转字符画的示例
2017/08/22 Python
pandas 对每一列数据进行标准化的方法
2018/06/09 Python
python 中字典嵌套列表的方法
2018/07/03 Python
python selenium 查找隐藏元素 自动播放视频功能
2019/07/24 Python
python实现udp传输图片功能
2020/03/20 Python
基于python requests selenium爬取excel vba过程解析
2020/08/12 Python
Python 创建守护进程的示例
2020/09/29 Python
在Python中字典按值排序的实现方法
2020/11/12 Python
Scrapy实现模拟登录的示例代码
2021/02/21 Python
Html5插件教程之添加浏览器放大镜效果的商品橱窗
2016/01/07 HTML / CSS
网络技术支持面试题
2013/04/22 面试题
工商企业管理应届生求职信
2013/11/03 职场文书
手工社团活动方案
2014/02/17 职场文书
出国签证在职证明
2014/09/20 职场文书
领导干部贪图享乐整改措施
2014/09/21 职场文书
交通运输局四风问题对照检查材料思想汇报
2014/10/09 职场文书
人与自然的观后感
2015/06/18 职场文书
社区服务活动感想
2015/08/11 职场文书
运动会100米广播稿
2015/08/19 职场文书