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 相关文章推荐
服务端 VBScript 与 JScript 几个相同特性的写法 By shawl.qiu
Mar 06 Javascript
Javascript基础教程之数据类型 (数值 Number)
Jan 18 Javascript
javascript图片预加载实例分析
Jul 16 Javascript
使用pcs api往免费的百度网盘上传下载文件的方法
Mar 17 Javascript
使用JS动态显示文本
Sep 09 Javascript
Vue 路由 过渡动效 数据获取方法
Jul 31 Javascript
解决vue attr取不到属性值的问题
Sep 18 Javascript
js实现图片推拉门效果代码实例
May 18 Javascript
Vue实现页面添加水印功能
Nov 09 Javascript
JavaScript装饰者模式原理与用法实例详解
Mar 09 Javascript
JavaScript事件循环及宏任务微任务原理解析
Sep 02 Javascript
如何通过Proxy实现JSBridge模块化封装
Oct 22 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
剧场版动画《PSYCHO-PASS 3 FIRST INSPECTOR》3月27日日本上映!
2020/03/06 日漫
php将金额数字转化为中文大写
2015/07/09 PHP
深入理解PHP的远程多会话调试
2017/09/21 PHP
不用AJAX和IFRAME,说说真正意义上的ASP+JS无刷新技术
2008/09/25 Javascript
关于锚点跳转及jQuery下相关操作与插件
2012/10/01 Javascript
借助script进行Http跨域请求:JSONP实现原理及代码
2013/03/19 Javascript
javascript操作html控件实例(javascript添加html)
2013/12/02 Javascript
使用js判断TextBox控件值改变然后出发事件
2014/03/07 Javascript
使用Browserify配合jQuery进行编程的超级指南
2015/07/28 Javascript
js的form表单提交url传参数(包含+等特殊字符)的两种解决方法
2016/05/25 Javascript
Javascript计算二维数组重复值示例代码
2016/12/18 Javascript
canvas绘制万花筒效果(代码分享)
2017/01/20 Javascript
JS正则表达式验证密码格式的集中情况总结
2017/02/23 Javascript
Vue.2.0.5过渡效果使用技巧
2017/03/16 Javascript
JavaScript中使用webuploader实现上传视频功能(demo)
2017/04/10 Javascript
vue中如何引入jQuery和Bootstrap
2017/04/10 jQuery
浅谈react-native热更新react-native-pushy集成遇到的问题
2017/09/30 Javascript
elementUI select组件默认选中效果实现的方法
2019/03/25 Javascript
vue实现文字横向无缝走马灯组件效果的实例代码
2019/04/09 Javascript
小程序如何写动态标签的实现方法
2020/02/05 Javascript
vue 动态组件(component :is) 和 dom元素限制(is)用法说明
2020/09/04 Javascript
关于vue 项目中浏览器跨域的配置问题
2020/11/10 Javascript
Vue-router中hash模式与history模式的区别详解
2020/12/15 Vue.js
python通过自定义isnumber函数判断字符串是否为数字的方法
2015/04/23 Python
OpenCV-Python实现轮廓检测实例分析
2018/01/05 Python
Python实现朴素贝叶斯的学习与分类过程解析
2019/08/24 Python
keras CNN卷积核可视化,热度图教程
2020/06/22 Python
Python库安装速度过慢解决方案
2020/07/14 Python
Python中猜拳游戏与猜筛子游戏的实现方法
2020/09/04 Python
python爬取音频下载的示例代码
2020/10/19 Python
深入浅析css3 中display box使用方法
2015/11/25 HTML / CSS
德国隐形眼镜店:LuckyLens
2018/07/29 全球购物
班级活动总结格式
2014/08/30 职场文书
复试通知单模板
2015/04/24 职场文书
亮剑观后感300字
2015/06/05 职场文书
大学生十八大感想
2015/08/11 职场文书