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 相关文章推荐
Firefox下提示illegal character并出现乱码的原因
Mar 25 Javascript
js null undefined 空区别说明
Jun 13 Javascript
基于jquery的横向滚动条(滑动条)
Feb 24 Javascript
jQuery获取样式中的背景颜色属性值/颜色值
Dec 17 Javascript
Javascript实现滑块滑动改变值的实现代码
Apr 12 Javascript
node.js使用nodemailer发送邮件实例
Mar 10 Javascript
jquery 自定义容器下雨效果可将下雨图标改为其他
Apr 23 Javascript
用JavaScript实现使用鼠标画线的示例代码
Aug 19 Javascript
JS实现网页上随机产生超链接地址的方法
Nov 09 Javascript
jquery中关于bind()方法的使用技巧分享
Mar 30 jQuery
详解Nuxt内导航栏的两种实现方式
Apr 16 Javascript
echarts柱状图背景重叠组合而非并列的实现代码
Dec 10 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中使用CURL伪造来路抓取页面或文件
2011/05/04 PHP
一个图片地址分解程序(用于PHP小偷程序)
2014/08/23 PHP
php自定义hash函数实例
2015/05/05 PHP
屏蔽PHP默认设置中的Notice警告的方法
2016/05/20 PHP
List the UTC Time on a Computer
2007/06/11 Javascript
IE/FireFox具备兼容性的拖动代码
2007/08/13 Javascript
Firefox中beforeunload事件的实现缺陷浅析
2012/05/03 Javascript
javascript仿php的print_r函数输出json数据
2013/09/13 Javascript
jquery实现图片翻页效果
2013/12/23 Javascript
jquery操作checked属性以及disabled属性的多种方法
2014/06/20 Javascript
js通过location.search来获取页面传来的参数
2014/09/11 Javascript
JavaScript实现twitter puddles算法实例
2014/12/06 Javascript
详细解读JavaScript的跨浏览器事件处理
2015/08/12 Javascript
JavaScript中日期的相关操作方法总结
2015/10/24 Javascript
javascript封装addLoadEvent实现页面同时加载执行多个函数的方法
2016/07/25 Javascript
bootstrap table小案例
2016/10/21 Javascript
jQuery中$.grep() 过滤函数 数组过滤
2016/11/22 Javascript
原生JS改变透明度实现轮播效果
2017/03/24 Javascript
js实现会跳动的日历效果(完整实例)
2017/10/18 Javascript
解析Angular 2+ 样式绑定方式
2018/01/15 Javascript
使用PyCharm配合部署Python的Django框架的配置纪实
2015/11/19 Python
对python dataframe逻辑取值的方法详解
2019/01/30 Python
python异步Web框架sanic的实现
2020/04/27 Python
keras 多任务多loss实例
2020/06/22 Python
OpenCV 使用imread()函数读取图片的六种正确姿势
2020/07/09 Python
浅谈python锁与死锁问题
2020/08/14 Python
Calzedonia美国官网:意大利风格袜子、打底裤和沙滩装
2018/07/19 全球购物
洛杉矶时尚女装系列:J.ING US
2019/03/17 全球购物
道路建设实施方案
2014/03/18 职场文书
广播节目策划方案
2014/05/23 职场文书
运动会的口号
2014/06/09 职场文书
领导干部民主生活会自我剖析材料范文
2014/09/20 职场文书
软弱涣散基层党组织整改方案
2014/10/25 职场文书
社区节水倡议书
2015/04/29 职场文书
旅行社计调工作总结
2015/08/12 职场文书
入团申请书格式
2019/06/20 职场文书