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 cookies操作集合
Apr 12 Javascript
基于jQuery的倒计时插件代码
May 07 Javascript
Javascript 检测键盘按键信息及键码值对应介绍
Jan 03 Javascript
JS文本框不能输入空格验证方法
Mar 19 Javascript
jquery 显示*天*时*分*秒实现时间计时器
May 07 Javascript
js创建一个input数组并绑定click事件的方法
Jun 12 Javascript
JavaScript字符串常用类使用方法汇总
Apr 14 Javascript
微信支付如何实现内置浏览器的H5页面支付
Sep 25 Javascript
几种二级联动案例(jQuery\Array\Ajax php)
Aug 13 Javascript
详解服务端预渲染之Nuxt(介绍篇)
Apr 07 Javascript
微信小程序+云开发实现欢迎登录注册
May 24 Javascript
Webpack中SplitChunksPlugin 配置参数详解
Mar 24 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的session cookie错误
2009/08/09 PHP
phpmyadmin安装时提示:Warning: require_once(./libraries/common.inc.php)错误解决办法
2011/08/18 PHP
joomla jce editor 解决上传中文名文件失败问题
2013/06/09 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十五)
2014/06/30 PHP
laravel 5 实现模板主题功能(续)
2015/03/02 PHP
PHP中读取文件的几个方法总结(推荐)
2016/06/03 PHP
3种方法轻松处理php开发中emoji表情的问题
2016/07/18 PHP
PHP搭建大文件切割分块上传功能示例
2017/01/04 PHP
Aster vs KG BO3 第二场2.19
2021/03/10 DOTA
取得父标签
2006/11/14 Javascript
jQuery之尺寸调整组件的深入解析
2013/06/19 Javascript
js实现iPhone界面风格的单选框和复选框按钮实例
2015/08/18 Javascript
node.js路径处理方法以及绝对路径详解
2021/03/04 Javascript
Bootstrap 轮播(Carousel)插件
2016/12/26 Javascript
canvas学习之API整理笔记(一)
2016/12/29 Javascript
Node.js复制文件的方法示例
2016/12/29 Javascript
几种响应式文字详解
2017/05/19 Javascript
js实现京东轮播图效果
2017/06/30 Javascript
Vue二次封装axios为插件使用详解
2018/05/21 Javascript
通过高德地图API获得某条道路上的所有坐标用于描绘道路的方法
2020/08/24 Javascript
改进Django中的表单的简单方法
2015/07/17 Python
Django实现快速分页的方法实例
2017/10/22 Python
python GUI框架pyqt5 对图片进行流式布局的方法(瀑布流flowlayout)
2020/03/12 Python
Pytorch之Tensor和Numpy之间的转换的实现方法
2020/09/03 Python
css3实现简单的白云飘动背景特效
2020/10/28 HTML / CSS
纽约家具、家居装饰和地毯店:ABC Carpet & Home
2017/06/21 全球购物
Giglio英国站:意大利奢侈品购物网
2018/03/06 全球购物
90后毕业生的求职信范文
2013/09/21 职场文书
师范生实习个人的自我评价
2013/09/28 职场文书
产品销售员岗位职责
2013/12/18 职场文书
2014年骨干教师工作总结
2014/12/19 职场文书
2015年秋季小学开学典礼主持词
2015/07/16 职场文书
最美劳动诗,致敬所有的劳动者!
2019/07/12 职场文书
golang特有程序结构入门教程
2021/06/02 Python
OpenCV-Python实现油画效果的实例
2021/06/08 Python
Python数据可视化之Seaborn的安装及使用
2022/04/19 Python