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 相关文章推荐
免费空间广告万能消除代码
Sep 04 Javascript
javascript+xml实现简单图片轮换(只支持IE)
Dec 23 Javascript
JavaScript不刷新实现浏览器的前进后退功能
Nov 05 Javascript
javascript的tab切换原理与效果实现方法
Jan 10 Javascript
javascript跨域方法、原理以及出现问题解决方法(详解)
Aug 06 Javascript
jquery转盘抽奖功能实现
Nov 13 Javascript
JavaScript位移运算符(无符号) &gt;&gt;&gt; 三个大于号 的使用方法详解
Mar 31 Javascript
jquery中ajax请求后台数据成功后既不执行success也不执行error的完美解决方法
Dec 24 jQuery
js中数组常用方法总结(推荐)
Apr 09 Javascript
微信小程序实现的一键连接wifi功能示例
Apr 24 Javascript
javascript中的with语句学习笔记及用法
Feb 17 Javascript
JS数组去重详情
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
中国的第一台收音机
2021/03/01 无线电
php使用Jpgraph绘制3D饼状图的方法
2015/06/10 PHP
WAMP环境中扩展oracle函数库(oci)
2015/06/26 PHP
PHP模糊查询的实现方法(推荐)
2016/09/06 PHP
经典的解除许多网站无法复制文字的绝招
2006/12/31 Javascript
input按钮的事件处理大全
2010/12/10 Javascript
JavaScript实现的简单幂函数实例
2015/04/17 Javascript
在JS方法中返回多个值的方法汇总
2015/05/20 Javascript
JavaScript调用浏览器打印功能实例分析
2015/07/17 Javascript
JS脚本根据手机浏览器类型跳转WAP手机网站(两种方式)
2015/08/04 Javascript
AngularJS 实现弹性盒子布局的方法
2016/08/30 Javascript
AngularJS入门教程之与服务器(Ajax)交互操作示例【附完整demo源码下载】
2016/11/02 Javascript
Bootstrap源码解读下拉菜单(4)
2016/12/23 Javascript
用React-Native+Mobx做一个迷你水果商城APP(附源码)
2017/12/25 Javascript
Vue.js实现可配置的登录表单代码详解
2018/03/29 Javascript
JavaScript DOM元素常见操作详解【添加、删除、修改等】
2018/05/09 Javascript
ant-design-vue中的select选择器,对输入值的进行筛选操作
2020/10/24 Javascript
[02:57]DOTA2英雄基础教程 风行者
2014/01/16 DOTA
[53:03]Optic vs TNC 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python面向对象编程基础解析(二)
2017/10/26 Python
Python 修改列表中的元素方法
2018/06/26 Python
python 解决cv2绘制中文乱码问题
2019/12/23 Python
Django+Celery实现动态配置定时任务的方法示例
2020/05/26 Python
Python3中对json格式数据的分析处理
2021/01/28 Python
多重CSS背景动画实现方法示例
2014/04/04 HTML / CSS
html5 跨文档消息传输示例探讨
2013/04/01 HTML / CSS
加拿大最大的箱包及旅游配件零售商:Bentley Leathers
2017/07/19 全球购物
科室工作的个人自我评价
2013/10/30 职场文书
找工作最新求职信
2013/12/22 职场文书
销售辞职报告范文
2014/01/12 职场文书
特色蛋糕店创业计划书
2014/01/28 职场文书
群众路线教育党课主持词
2014/04/01 职场文书
减负增效提质方案
2014/05/23 职场文书
运动会闭幕式通讯稿
2015/07/18 职场文书
SQLServer2019 数据库的基本使用之图形化界面操作的实现
2021/04/08 SQL Server
vue封装数字翻牌器
2022/04/20 Vue.js