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 相关文章推荐
javascript 写类方式之四
Jul 05 Javascript
event.X和event.clientX的区别分析
Oct 06 Javascript
jQuery表单美化插件jqTransform使用详解
Apr 12 Javascript
node.js 动态执行脚本
Jun 02 Javascript
JavaScript如何实现跨域请求
Aug 05 Javascript
JQuery 进入页面默认给已赋值的复选框打钩
Mar 23 jQuery
原生js实现简单的链式操作
Jul 04 Javascript
薪资那么高的Web前端必看书单
Oct 13 Javascript
node结合swig渲染摸板的方法
Apr 11 Javascript
详解Vue取消eslint语法限制
Aug 04 Javascript
webpack4打包vue前端多页面项目
Sep 17 Javascript
js嵌套的数组扁平化:将多维数组变成一维数组以及push()与concat()区别的讲解
Jan 19 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
PH P5.2至5.5、5.6的新增功能详解
2014/07/14 PHP
CI框架入门示例之数据库取数据完整实现方法
2014/11/05 PHP
php常用字符串处理函数实例分析
2014/11/22 PHP
PHP中实现crontab代码分享
2015/03/26 PHP
php实现随机生成易于记忆的密码
2015/06/19 PHP
php arsort 数组降序排序详细介绍
2016/11/17 PHP
JavaScript高级程序设计
2006/12/29 Javascript
javascript得到XML某节点的子节点个数的脚本
2008/10/11 Javascript
验证码按回车不变解决方法
2013/03/29 Javascript
JS函数this的用法实例分析
2015/02/05 Javascript
Clipboard.js 无需Flash的JavaScript复制粘贴库
2015/10/02 Javascript
轻松搞定jQuery.noConflict()
2016/02/15 Javascript
js运动事件函数详解
2016/10/21 Javascript
Node.js利用Net模块实现多人命令行聊天室的方法
2016/12/23 Javascript
Omi v1.0.2发布正式支持传递javascript表达式
2017/03/21 Javascript
[51:36]Optic vs Newbee 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python匹配中文的正则表达式
2016/05/11 Python
Python 内置函数memoryview(obj)的具体用法
2017/11/23 Python
python爬取亚马逊书籍信息代码分享
2017/12/09 Python
python编写微信远程控制电脑的程序
2018/01/05 Python
浅谈django rest jwt vue 跨域问题
2018/10/26 Python
使用python实现http及ftp服务进行数据传输的方法
2018/10/26 Python
python应用Axes3D绘图(批量梯度下降算法)
2020/03/25 Python
django的autoreload机制实现
2020/06/03 Python
Python 必须了解的5种高级特征
2020/09/10 Python
Python基于Serializer实现字段验证及序列化
2020/11/04 Python
英国奢侈品网站:MatchesFashion
2016/12/16 全球购物
欧洲最大的化妆品连锁公司:Douglas道格拉斯
2017/05/06 全球购物
财务管理专业毕业生求职信范文
2013/09/21 职场文书
地理信息科学专业推荐信
2014/09/08 职场文书
2016公司中秋节寄语
2015/12/07 职场文书
MySQL 如何分析查询性能
2021/05/12 MySQL
Win11如何修改dns?Win11修改dns图文教程
2022/01/18 数码科技
Java生成日期时间存入Mysql数据库的实现方法
2022/03/03 Java/Android
我收到了德劲DE1107
2022/04/05 无线电
华为HarmonyOS3.0强在哪? 看看鸿蒙3.0这7个小功能
2023/01/09 数码科技