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 操作select相关方法函数
Dec 06 Javascript
js 点击按钮弹出另一页,选择值后,返回到当前页
May 26 Javascript
javascript中with()方法的语法格式及使用
Aug 04 Javascript
jQuery实现点击小图片淡入淡出显示大图片特效
Sep 09 Javascript
原生JS封装ajax 传json,str,excel文件上传提交表单(推荐)
Jun 21 Javascript
React Native第三方平台分享的实例(Android,IOS双平台)
Aug 04 Javascript
vue动画打包后失效问题的解决方法
Sep 18 Javascript
a标签调用js的方法总结
Sep 05 Javascript
微信小程序图片自适应实现解析
Jan 21 Javascript
详解微信小程序入门从这里出发(登录注册、开发工具、文件及结构介绍)
Jul 21 Javascript
js删除对象中的某一个字段的方法实现
Jan 11 Javascript
js实现Element中input组件的部分功能并封装成组件(实例代码)
Mar 02 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
WordPress中转义HTML与过滤链接的相关PHP函数使用解析
2015/12/22 PHP
js判断FCKeditor内容是否为空的两种形式
2013/05/14 Javascript
指定区域的图片自动按比例缩小的js代码(防止页面被图片撑破)
2014/02/21 Javascript
JavaScript学习笔记(三):JavaScript也有入口Main函数
2015/09/12 Javascript
javascript获取wx.config内部字段解决微信分享
2016/03/09 Javascript
jQuery插件Easyui设置datagrid的pageNumber导致两次请求问题的解决方法
2016/08/06 Javascript
JS添加或修改控件的样式(Class)实现方法
2016/10/15 Javascript
jQuery操作json常用方法示例
2017/01/04 Javascript
JS+Canvas绘制动态时钟效果
2017/11/10 Javascript
Vue组件中slot的用法
2018/01/30 Javascript
koa上传excel文件并解析的实现方法
2018/08/09 Javascript
vue+axios 前端实现的常用拦截的代码示例
2018/08/23 Javascript
浅谈Angular单元测试总结
2019/03/22 Javascript
微信小程序上传帖子的实例代码(含有文字图片的微信验证)
2020/07/11 Javascript
详解Node.JS模块 process
2020/08/31 Javascript
vue项目中企业微信使用js-sdk时config和agentConfig配置方式详解
2020/12/15 Vue.js
Python 文件重命名工具代码
2009/07/26 Python
python实现12306抢票及自动邮件发送提醒付款功能
2018/03/08 Python
Linux下python3.7.0安装教程
2018/07/30 Python
Python实现打砖块小游戏代码实例
2019/05/18 Python
微信公众号token验证失败解决方案
2019/07/22 Python
python opencv根据颜色进行目标检测的方法示例
2020/01/15 Python
python与pycharm有何区别
2020/07/01 Python
css3 transform 3d 使用css3创建动态3d立方体(html5实践)
2013/01/06 HTML / CSS
Pretty Little Thing爱尔兰:时尚女性服饰
2017/03/27 全球购物
Giglio美国站:意大利奢侈品购物网
2018/02/10 全球购物
年度考核自我鉴定
2013/11/09 职场文书
2014年党支部承诺书
2014/05/30 职场文书
增员口号大全
2014/06/18 职场文书
党员四风问题个人对照检查材料
2014/10/26 职场文书
社区工作者个人总结
2015/02/28 职场文书
庆祝教师节主持词
2015/07/06 职场文书
公司出差管理制度范本
2015/08/05 职场文书
幼儿园托班教育随笔
2015/08/14 职场文书
2016党员干部政治学习心得体会
2016/01/23 职场文书
Python3 如何开启自带http服务
2021/05/18 Python