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中ajax学习笔记3
Oct 16 Javascript
JAVASCRIPT函数作用域和提前声明 分享
Aug 22 Javascript
遍历DOM对象内的元素属性示例代码
Feb 08 Javascript
JavaScript判断字符长度、数字、Email、电话等常用判断函数分享
Apr 01 Javascript
基于JavaScript实现动态添加删除表格的行
Feb 01 Javascript
jQuery通用的全局遍历方法$.each()用法实例
Jul 04 Javascript
angular2中Http请求原理与用法详解
Jan 11 Javascript
iview table高度动态设置方法
Mar 14 Javascript
vue中使用 pako.js 解密 gzip加密字符串的方法
Jun 10 Javascript
详解package.json版本号规则
Aug 01 Javascript
原生JS实现萤火虫效果
Mar 07 Javascript
JS Generator 函数的含义与用法实例总结
Apr 08 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
比特率,大家看看这个就不用收音机音质去比MP3音质了
2021/03/01 无线电
ThinkPHP的L方法使用简介
2014/06/18 PHP
ThinkPHP访问不存在的模块跳转到404页面的方法
2014/06/19 PHP
php判断两个日期之间相差多少个月份的方法
2015/06/18 PHP
PHP概率计算函数汇总
2015/09/13 PHP
PHP的几个常用加密函数
2016/02/03 PHP
详解Yii2 rules 的验证规则
2016/12/02 PHP
php利用云片网实现短信验证码功能的示例代码
2017/11/18 PHP
php设计模式之代理模式分析【星际争霸游戏案例】
2020/03/23 PHP
浅析PHP中json_encode与json_decode的区别
2020/07/15 PHP
判断多个元素(RADIO,CHECKBOX等)是否被选择的原理说明
2009/02/18 Javascript
JS HTML5 音乐天气播放器(Ajax获取天气信息)
2013/05/26 Javascript
JavaScript 命名空间 使用介绍
2013/08/29 Javascript
JS与C#编码解码
2013/12/03 Javascript
jquery操作checkbox示例分享
2014/07/21 Javascript
js实现超简单的展开、折叠目录代码
2015/08/28 Javascript
json传值以及ajax接收详解
2016/05/24 Javascript
jquery 将当前时间转换成yyyymmdd格式的实现方法
2016/06/01 Javascript
vue路由--网站导航功能详解
2019/03/29 Javascript
在Python的Bottle框架中使用微信API的示例
2015/04/23 Python
使用Python编写简单的端口扫描器的实例分享
2015/12/18 Python
python中快速进行多个字符替换的方法小结
2016/12/15 Python
Windows 8.1 64bit下搭建 Scrapy 0.22 环境
2018/11/18 Python
对python 多个分隔符split 的实例详解
2018/12/20 Python
python程序快速缩进多行代码方法总结
2019/06/23 Python
Atom Python 配置Python3 解释器的方法
2019/08/28 Python
Python爬虫分析微博热搜关键词的实现代码
2021/02/22 Python
微软新西兰官方网站:Microsoft New Zealand
2018/08/17 全球购物
美国唇部护理专家:Sara Happ
2019/06/19 全球购物
实习评语大全
2014/04/26 职场文书
党旗在我心中演讲稿
2014/09/15 职场文书
医院见习报告范文
2014/11/03 职场文书
大学生志愿者心得体会
2016/01/15 职场文书
python pyhs2 的安装操作
2021/04/07 Python
实例详解Python的进程,线程和协程
2022/03/13 Python
Python实现灰色关联分析与结果可视化的详细代码
2022/03/25 Python