Vue.js中provide/inject实现响应式数据更新的方法示例


Posted in Javascript onOctober 16, 2019

vue.js官方文档:https://cn.vuejs.org/v2/api/#provide-inject

首先假设我们在祖辈时候传入进来是个动态的数据,官方不是说如果你传入了一个可监听的对象,那么其对象还是可响应的么?

parent父页面:

export default {
 provide() {
  return  { foo: this.fonnB }
 },
 data(){
  return { fonnB: 'old word '} 
 }
created() {
  setTimeout(()=>{
   this.fonnB = 'new words';  // 这里仅仅foonB变化了,foo没有变化
   this._provided.foo="new words"; // 这里foo变化了,但子组件获得的foo 依旧是old words
   console.log( this._provided);
  },1000)
 },
}

child子页面:

export default {
 inject:['foo'],
 data(){
  return { chilrfoo: this.foo } 
 },
 created() {
  setTimeout(()=>{
   // 子组件获得的foo 依旧是old words
   console.log( this.foo)
  },2000)
 }
}

结果:

通过上面方式,经过验证,子组件页面都没办法实现响应更新this.foo的值。可能我们对官方理解还是有误,下面通过网上资料和自己构思实现了响应式数据更新

示例(结果仍不可行)

很明显上面再父组件定时器内我们是改变了数据源,这个时候我们就在想,我们改变的数据到底有没有传入到子孙组件中,那么要验证这个问题,我们不妨可以在子孙组件中手动写set 函数,computed 本身就只相当于一个get函数,当然,你也可以试试watch

parent父页面:

export default {
provide() {
   return  { foo: this.fonnB }
  },
  data(){
   return {
    fonnB: 'old word'
   } 
  }
   created() {
   setTimeout(()=>{
    this.fonnB = "new words";  
    // 这里foo变化了,但子组件获得的foo 依旧是old words
   },1000)

  },

 }

child子页面:

export default {
  inject:['foo'],
  data(){
   return {
    childfooOld: this.foo
   } 
  },
  computed:{
    chilrdfoo() {
      return this.foo
    }
  },
 created () {
    console.log(this.foo)
    // -> 'old word'
    setTimeout(() => {
      console.log(this.chilrdfoo); // 这里计算属性依旧是old words
    }, 2000);
   }
 }

通过computed,我们都知道data中有get/set,数据也是响应式的,但为什么没更新,有点疑惑,如果有大佬知道能解释清楚的可以探讨。

但是,但是,但是!实际需求肯定没有这么简单,往往我们需要的是共享父组件里面的动态数据,这些数据可能来自于data 或者 store。 就是说父组件里面的数据发生变化之后,需要同步到子孙组件里面。这时候该怎么做呢?
我想的是将一个函数赋值给provide的一个值,这个函数返回父组件的动态数据,然后在子孙组件里面调用这个函数。
实际上这个函数存储了父组件实例的引用,所以每次子组件都能获取到最新的数据。代码长下面的样子:

Parent组件:

<template>
  <div class="parent-container">
   Parent组件
   <br/>
   <button type="button" @click="changeName">改变name</button>
   <br/>
   Parent组件中 name的值: {{name}}
   <Child v-bind="{name: 'k3vvvv'}" />
  </div>
</template>

<style scoped>
 .parent-container {
  padding: 30px;
  border: 1px solid burlywood;
 }
</style>

<script>
import Child from './Child'
export default {
 name: 'Parent',
 data () {
  return {
   name: 'Kevin'
  }
 },
 methods: {
  changeName (val) {
   this.name = 'Kev'
  }
 },
 provide: function () {
  return {
   nameFromParent: this.name,
   getReaciveNameFromParent: () => this.name
  }
 },
 // provide: {
 // nameFromParent: this.name,
 // getReaciveNameFromParent: () => this.name
 // },
 components: {
  Child
 }
}
</script>

Child组件

<template>
 <div class="child-container">
  Child组件
  <br/>
  <GrandSon />
 </div>
</template>
<style scoped>
 .child-container {
  padding: 30px;
  border: 1px solid burlywood;
 }
</style>
<script>
import GrandSon from './GrandSon'
export default {
 components: {
  GrandSon
 }
}
</script>

GrandSon组件:

<template>
 <div class="grandson-container">
  Grandson组件
  <br/>
  {{nameFromParent}}
  <br/>
  {{reactiveNameFromParent}}
 </div>
</template>
<style scoped>
 .grandson-container {
  padding: 30px;
  border: 1px solid burlywood;
 }
</style>
<script>
export default {
 inject: ['nameFromParent', 'getReaciveNameFromParent'],
 computed: {
  reactiveNameFromParent () {
   return this.getReaciveNameFromParent()
  }
 },
 watch: {
  'reactiveNameFromParent': function (val) {
   console.log('来自Parent组件的name值发生了变化', val)
  }
 },
 mounted () {
  console.log(this.nameFromParent, 'nameFromParent')
 }
}
</script>

结果:

来自于reactiveNameFromParent ,随着祖先组件变化而变化了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery操作input值的各种方法总结
Nov 21 Javascript
Javascript实现滚动图片新闻的实例代码
Nov 27 Javascript
基于Jquery和html5实现炫酷的3D焦点图动画
Mar 02 Javascript
jquery配合.NET实现点击指定绑定数据并且能够一键下载
Oct 28 Javascript
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
Dec 15 Javascript
利用 spin.js 生成等待效果(js 等待效果)
Jun 25 Javascript
温故知新——JavaScript中的字符串连接问题最全总结(推荐)
Aug 21 Javascript
Angularjs实现上传图片预览功能
Sep 01 Javascript
详解http访问解析流程原理
Oct 18 Javascript
响应式框架Bootstrap栅格系统的实例
Dec 19 Javascript
Angular服务Request异步请求的实例讲解
Aug 13 Javascript
vue中轮训器的使用
Jan 27 Javascript
javascript实现点亮灯泡特效示例
Oct 15 #Javascript
vue-cli 为项目设置别名的方法
Oct 15 #Javascript
Vue 实现输入框新增搜索历史记录功能
Oct 15 #Javascript
Centos7 安装Node.js10以上版本的方法步骤
Oct 15 #Javascript
微信小程序如何实现五星评价功能
Oct 15 #Javascript
node.js express框架实现文件上传与下载功能实例详解
Oct 15 #Javascript
ES6 Promise对象概念及用法实例详解
Oct 15 #Javascript
You might like
数组与类使用PHP的可变变量名需要的注意的问题
2013/06/20 PHP
php5.5新数组函数array_column使用
2013/07/08 PHP
PHP中批量生成静态html(命令行下运行PHP)
2014/04/19 PHP
js option删除代码集合
2008/11/12 Javascript
js textarea自动增高并隐藏滚动条
2009/12/16 Javascript
BOM与DOM的区别分析
2010/10/26 Javascript
JavaScript 高级篇之函数 (四)
2012/04/07 Javascript
ajax异步刷新实现更新数据库
2012/12/03 Javascript
Javascript在IE和FireFox中的不同表现简析
2012/12/03 Javascript
Javascript 浮点运算的问题分析与解决方法
2013/08/27 Javascript
如何学习Javascript入门指导
2013/11/01 Javascript
ParseInt函数参数设置介绍
2014/01/02 Javascript
BootStrap 附加导航组件
2016/07/22 Javascript
禁用backspace网页回退功能的实现代码
2016/11/15 Javascript
js微信扫描二维码登录网站技术原理
2016/12/01 Javascript
在javascript中,null>=0 为真,null==0却为假,null的值详解
2017/02/22 Javascript
微信小程序分享功能之按钮button 边框隐藏和点击隐藏
2018/06/14 Javascript
Node.js Koa2使用JWT进行鉴权的方法示例
2018/08/17 Javascript
vue3.0 加载json的方法(非ajax)
2020/10/26 Javascript
[01:00:14]DOTA2-DPC中国联赛 正赛 Ehome vs Elephant BO3 第二场 2月28日
2021/03/11 DOTA
Python切换pip安装源的方法详解
2016/11/18 Python
python读取中文txt文本的方法
2018/04/12 Python
Python中的Numpy矩阵操作
2018/08/12 Python
Python 3.6 中使用pdfminer解析pdf文件的实现
2019/09/25 Python
Python笔记之代理模式
2019/11/20 Python
django实现后台显示媒体文件
2020/04/07 Python
Matplotlib中rcParams使用方法
2021/01/05 Python
pycharm 实现复制一行的快捷键
2021/01/15 Python
个性化皮包、小袋、生活配件:Mon Purse
2019/03/26 全球购物
编码实现字符串转整型的函数
2012/06/02 面试题
生产班组长岗位职责
2014/01/05 职场文书
会计辞职信范文
2014/01/15 职场文书
竞选大队干部演讲稿
2014/09/11 职场文书
语文复习计划
2015/01/19 职场文书
合作与交流自我评价
2015/03/09 职场文书
正确使用MySQL INSERT INTO语句
2021/05/26 MySQL