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 相关文章推荐
一些相见恨晚的 JavaScript 技巧
Apr 25 Javascript
JavaScript 高级篇之DOM文档,简单封装及调用、动态添加、删除样式(六)
Apr 07 Javascript
html页面显示年月日时分秒和星期几的两种方式
Aug 20 Javascript
JS高级调试技巧:捕获和分析 JavaScript Error详解
Mar 16 Javascript
使用Javascript监控前端相关数据的代码
Oct 27 Javascript
详解Angular CLI + Electron 开发环境搭建
Jul 20 Javascript
jQuery EasyUI结合zTree树形结构制作web页面
Sep 01 jQuery
Bootstrap一款超好用的前端框架
Sep 25 Javascript
vue中引用swiper轮播插件的教程详解
Aug 16 Javascript
js canvas画布实现高斯模糊效果
Nov 27 Javascript
jQuery擦除插件eraser使用方法详解
Jan 11 jQuery
详解JavaScript数据类型和判断方法
Sep 04 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的库,结果发现很多东西
2006/12/31 PHP
PHP限制页面只能在微信自带浏览器访问的代码
2014/01/15 PHP
php面向对象程序设计中self与static的区别分析
2019/05/21 PHP
JavaScript 模仿vbs中的 DateAdd() 函数的代码
2007/08/13 Javascript
jquery 简短右键菜单 多浏览器兼容
2010/01/01 Javascript
选择TreeView控件的树状数据节点的JS方法(jquery)
2010/02/06 Javascript
jquery选择器(常用选择器说明)
2010/09/28 Javascript
JS文本框追加多个下拉框的值的简单实例
2013/07/12 Javascript
JS 对输入框进行限制(常用的都有)
2013/07/30 Javascript
js仿土豆网带缩略图的焦点图片切换效果实现方法
2015/02/23 Javascript
javascript每日必学之循环
2016/02/19 Javascript
微信jssdk用法汇总
2016/07/16 Javascript
jQuery插件Validation快速完成表单验证的方式
2016/07/28 Javascript
BootStrap实现邮件列表的分页和模态框添加邮件的功能
2016/10/13 Javascript
详解vue指令与$nextTick 操作DOM的不同之处
2018/08/02 Javascript
详解vuex之store源码简单解析
2019/06/13 Javascript
VUE实现移动端列表筛选功能
2019/08/23 Javascript
vue data恢复初始化数据的实现方法
2019/10/31 Javascript
详解Python中映射类型(字典)操作符的概念和使用
2015/08/19 Python
django rest framework之请求与响应(详解)
2017/11/06 Python
解决python gdal投影坐标系转换的问题
2020/01/17 Python
Python接口测试get请求过程详解
2020/02/28 Python
基于virtualenv创建python虚拟环境过程图解
2020/03/30 Python
Python开发入门——迭代的基本使用
2020/09/03 Python
python读取图片颜色值并生成excel像素画的方法实例
2021/02/19 Python
美国高品质个性化珠宝销售网站:Jewlr
2018/05/03 全球购物
美国电力供应商店/电气批发商:USESI
2018/10/12 全球购物
一加手机美国官方网站:OnePlus美国
2019/09/19 全球购物
公司面试感谢信
2014/02/01 职场文书
中西医专业毕业生职业规划书
2014/02/24 职场文书
老干部工作先进事迹
2014/08/17 职场文书
社区文艺活动方案
2014/08/19 职场文书
数学教师求职信范文
2015/03/20 职场文书
小学副班长竞选稿
2015/11/21 职场文书
致创业您:正能量激励人心句子(48条)
2019/08/15 职场文书
MySQL之DML语言
2021/04/05 MySQL