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之六 缓存数据功能介绍
Jun 21 Javascript
JavaScript实现页面实时显示当前时间的简单实例
Jul 20 Javascript
JS控制日期显示的小例子
Nov 23 Javascript
jquery 获取 outerHtml 包含当前节点本身的代码
Oct 30 Javascript
实例分析javascript中的call()和apply()方法
Nov 28 Javascript
node.js中的fs.fsync方法使用说明
Dec 15 Javascript
JavaScript中使用Callback控制流程介绍
Mar 16 Javascript
JavaScript获取网页表单action属性的方法
Apr 02 Javascript
Javascript中字符串replace方法的第二个参数探究
Dec 05 Javascript
在element-ui的select下拉框加上滚动加载
Apr 18 Javascript
VUEX-action可以修改state吗
Nov 19 Javascript
JavaScript函数Call、Apply原理实例解析
Feb 17 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的控制语句
2006/10/09 PHP
php页面函数设置超时限制的方法
2014/12/01 PHP
PHP的new static和new self的区别与使用
2019/11/27 PHP
Javascript 篱式条件判断
2008/08/22 Javascript
JavaScript 学习笔记(十六) js事件
2010/02/01 Javascript
Javascript无参数和有参数类继承问题解决方法
2015/03/02 Javascript
JS中call/apply、arguments、undefined/null方法详解
2016/02/15 Javascript
常用的JQuery函数及功能小结
2016/03/24 Javascript
使用jQuery制作浮动工具栏的实例分享
2016/05/13 Javascript
把普通对象转换成json格式的对象的简单实例
2016/07/04 Javascript
jquery 仿锚点跳转到页面指定位置的实例
2017/02/14 Javascript
分析javascript原型及原型链
2018/03/18 Javascript
vue实现简单的MVVM框架
2018/08/05 Javascript
javascript实现留言板功能
2020/02/08 Javascript
jQuery AJAX应用实例总结
2020/05/19 jQuery
JSONP解决JS跨域问题的实现
2020/05/25 Javascript
JavaScript常用8种数组去重代码实例
2020/09/09 Javascript
vue Cli 环境删除与重装教程 - 版本文档
2020/09/11 Javascript
[04:27]2014DOTA2国际邀请赛 NAVI战队官方纪录片
2014/07/21 DOTA
在Python中使用M2Crypto模块实现AES加密的教程
2015/04/08 Python
Python多进程并发(multiprocessing)用法实例详解
2015/06/02 Python
Django的数据模型访问多对多键值的方法
2015/07/21 Python
python实现用户登录系统
2016/05/21 Python
Windows上使用Python增加或删除权限的方法
2018/04/24 Python
浅谈Python中eval的强大与危害
2019/03/13 Python
jupyter notebook 恢复误删单元格或者历史代码的实现
2020/04/17 Python
python 利用panda 实现列联表(交叉表)
2021/02/06 Python
python读取图片颜色值并生成excel像素画的方法实例
2021/02/19 Python
JD Sports德国官网:英国领先的运动鞋和运动服饰零售商
2018/02/26 全球购物
美国校服网上商店:French Toast
2019/10/08 全球购物
研究生毕业论文导师评语
2014/12/31 职场文书
稽核岗位职责
2015/02/10 职场文书
企业财务经理岗位职责
2015/04/08 职场文书
有关信念的名言语录集锦
2019/12/06 职场文书
nginx安装以及配置的详细过程记录
2021/09/15 Servers
Android实现获取短信验证码并自动填充
2023/05/21 Java/Android