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 相关文章推荐
js实现简单模态窗口,背景灰显
Nov 14 Javascript
为Extjs加加速(javascript加速)
Aug 19 Javascript
JavaScript通过元素索引号删除数组中对应元素的方法
Mar 18 Javascript
JS处理json日期格式化问题
Oct 01 Javascript
浅谈JavaScript 标准对象
Jun 02 Javascript
jQuery控制div实现随滚动条滚动效果
Jun 07 Javascript
使用Web Uploader实现多文件上传
Jun 08 Javascript
JavaScript中 ES6 generator数据类型详解
Aug 11 Javascript
vue-cli项目如何使用vue-resource获取本地的json数据(模拟服务端返回数据)
Aug 04 Javascript
jQuery使用ajax传递json对象到服务端及contentType的用法示例
Mar 12 jQuery
微信小程序实现文件预览
Oct 22 Javascript
详解vite+ts快速搭建vue3项目以及介绍相关特性
Feb 25 Vue.js
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 修改zen-cart下单和付款流程以防止漏单
2010/03/08 PHP
php检测网页是否被百度收录的函数代码
2013/10/09 PHP
PHP实现把MySQL数据库导出为.sql文件实例(仿PHPMyadmin导出功能)
2014/05/10 PHP
四个PHP非常实用的功能
2015/09/29 PHP
浅谈PHP中pack、unpack的详细用法
2018/03/12 PHP
jQuery源码分析之Event事件分析
2010/06/07 Javascript
在vs2010中调试javascript代码方法
2011/02/11 Javascript
jQuery ReferenceError: $ is not defined 错误的处理办法
2013/05/10 Javascript
JS往数组中添加项性能分析
2015/02/25 Javascript
js自制图片放大镜功能
2017/01/24 Javascript
Node.js环境下Koa2添加travis ci持续集成工具的方法
2017/06/19 Javascript
checkbox:click事件触发span元素内容改变的方法
2017/09/11 Javascript
Angular 4.x+Ionic3踩坑之Ionic3.x pop反向传值详解
2018/03/13 Javascript
JS实现常见的查找、排序、去重算法示例
2018/05/21 Javascript
React.js绑定this的5种方法(小结)
2018/06/05 Javascript
JS与jQuery判断文本框还剩多少字符可以输入的方法
2018/09/01 jQuery
使用jquery Ajax实现上传附件功能
2018/10/23 jQuery
关于vue项目中搜索节流的实现代码
2019/09/17 Javascript
Python模拟登录验证码(代码简单)
2016/02/06 Python
Python按行读取文件的简单实现方法
2016/06/22 Python
Python编程之event对象的用法实例分析
2017/03/23 Python
Python 内置函数memoryview(obj)的具体用法
2017/11/23 Python
python中利用h5py模块读取h5文件中的主键方法
2018/06/05 Python
Django中使用 Closure Table 储存无限分级数据
2019/06/06 Python
python3 批量获取对应端口服务的实例
2019/07/25 Python
浅谈python图片处理Image和skimage的区别
2019/08/04 Python
python爬虫学习笔记之pyquery模块基本用法详解
2020/04/09 Python
详解Django配置JWT认证方式
2020/05/09 Python
Python爬虫之Selenium警告框(弹窗)处理
2020/12/04 Python
Kent & Curwen:与大卫·贝克汉姆合作
2017/06/13 全球购物
毕业生自我推荐
2013/11/04 职场文书
村道德模范事迹材料
2014/08/28 职场文书
2014年政务公开工作总结
2014/12/09 职场文书
消费者理赔投诉书
2015/07/02 职场文书
2016新年年会主持词
2015/07/06 职场文书
2016年大学迎新工作总结
2015/10/14 职场文书