Vue data的数据响应式到底是如何实现的


Posted in Javascript onFebruary 11, 2020

研究过程

一般形式

data:{ n:0 } :以这样的方式存储数据,vue能够监听其变化吗?显然是不能的。

使用Obj.defineProperty

let data1 = {}

Object.defineProperty(data1, 'n', {
value: 0  
})

为什么要使用defineProperty呢?这不是把一般形式复杂化了吗?

引出主角getter setter。

如果我们想对数据监听进行处理呢?(假设修改的数据必须>=0)

let data2 = {}
data2._n = 0

Object.defineProperty(data2,'n',{
  get(){ return this._n },
  set(value){
    if(value<0) return //在此处可以对数据的修改进行操作
    this._n = value
  }
})

使用代理

如果对方直接修改data2._n怎么办?我们让data2变成匿名对象!

let data3 = proxy({ data:{n:0} }) //括号里是匿名对象,无法访问
function proxy({data}){
 const obj = {}
 Object.defineProperty(obj, 'n', {
  get(){
    return data.n
  },
  set(value){
    if(value<0)return
    data.n = value
   }
 })
 return obj // obj 就是代理
}

代理是什么?

  • 对data的属性的读写,全权交给另一个对象obj负责,那么obj就是data的代理
  • data.n不使用,偏要使用obj.n来操作data.n

如果用户自己给匿名对象起了个名字怎么办呢?

MyData = { n:0 }
let data3 = proxy({ data:MyData })
MyData.n = -1
 //成功赋值为-1

这种情况,我们也要进行拦截处理。

//在4.中的proxy函数中加入这几行
let value = data.n
 Object.defineProperty(data, 'n', {
   get(){
     return value
   },
   set(newValue){
     if(newValue<0)return
     value = newValue
   }
 })

这样,我们就对data进行了监听。

data域的一个bug

new Vue({
  data:{
    obj:{
      a:0
    }
  },
  template:`
    <div @click="set">{{ obj.b }}</div>
  `,
  methods:{
    set(){
      this.obj.b = 1
    }
  }
})
  //bug:vue无法监听一开始data域中不存在的obj.b

解决方法:

data的初始化中加入b

data:{
  obj:{
    a:0,
    b:undefined 
    //注意,vue中的null和undefined都不会被渲染出来
  }
}

使用Vue.set(this.obj,'b',1)

数组的长度又不固定,怎么提前声明?

  1. 使用Vue.set (不推荐)
  2. 使用this.array.push (被Vue改写过的push,实现了代理和监听)

详见vue文档,变异方法 章节

总结

//看看下面的代码,发现了什么?

let data = proxy({ data:myData5 })
let vm = new Vue({ data: myData })

Vue正是使用了这种代理和监听的设计模式,形成的数据响应式。

流程:声明数据 => 监听数据 => 代理数据 => 返回数据

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript对象的property和prototype是这样一种关系
Mar 24 Javascript
javascript 动态table添加colspan\rowspan 参数的方法
Jul 25 Javascript
7款吸引人眼球的jQuery/CSS3特效实例分享
Apr 25 Javascript
JavaScript设计模式之适配器模式介绍
Dec 28 Javascript
javascript实现页面刷新时自动清空表单并选中的方法
Jul 18 Javascript
jQuery购物网页经典制作案例
Aug 19 Javascript
JS中的作用域链
Mar 01 Javascript
JS实现二维数组横纵列转置的方法
Apr 17 Javascript
判断iOS、Android以及PC端的示例代码
Nov 15 Javascript
JS实现判断有效的数独算法示例
Feb 25 Javascript
微信小程序如何获取群聊的openGid以及名称详解
Jul 17 Javascript
解决vue中使用proxy配置不同端口和ip接口问题
Aug 14 Javascript
JS实现TITLE悬停长久显示效果完整示例
Feb 11 #Javascript
vue.config.js中配置Vue的路径别名的方法
Feb 11 #Javascript
vue-resourc发起异步请求的方法
Feb 11 #Javascript
js实现圆形显示鼠标单击位置
Feb 11 #Javascript
JavaScript实现省份城市的三级联动
Feb 11 #Javascript
node.js使用yargs处理命令行参数操作示例
Feb 11 #Javascript
node.js实现http服务器与浏览器之间的内容缓存操作示例
Feb 11 #Javascript
You might like
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2611816 bytes)
2014/11/08 PHP
微信支付之JSAPI公众号支付详解
2019/05/15 PHP
php中加密解密DES类的简单使用方法示例
2020/03/26 PHP
Jquery 基础学习笔记之文档处理
2009/05/29 Javascript
jQuery拖动图片删除示例
2013/05/10 Javascript
node.js中的path.isAbsolute方法使用说明
2014/12/08 Javascript
JS打开新窗口防止被浏览器阻止的方法
2015/01/03 Javascript
深入浅出理解javaScript原型链
2015/05/09 Javascript
Jquery使用css方法改变样式实例
2015/05/18 Javascript
jQuery+css实现的时钟效果(兼容各浏览器)
2016/01/27 Javascript
ui组件之input多选下拉实现方法(带有搜索功能)
2016/07/14 Javascript
JS实现数字格式千分位相互转换方法
2016/08/01 Javascript
React数据传递之组件内部通信的方法
2017/12/31 Javascript
webpack引入eslint配置详解
2018/01/22 Javascript
使用Vue.js开发微信小程序开源框架mpvue解析
2018/03/20 Javascript
一文搞懂ES6中的Map和Set
2019/05/20 Javascript
vuex实现数据状态持久化
2019/11/11 Javascript
JS实现简易留言板特效
2019/12/23 Javascript
Vue 实现v-for循环的时候更改 class的样式名称
2020/07/17 Javascript
Node在Controller层进行数据校验的过程详解
2020/08/28 Javascript
[02:39]我与DAC之Newbee.Moogy:从论坛到TI
2018/03/26 DOTA
[50:45]2018DOTA2亚洲邀请赛 4.6 淘汰赛 VP vs TNC 第一场
2018/04/10 DOTA
动感网页相册 python编写简单文件夹内图片浏览工具
2016/08/17 Python
python通过cookie模拟已登录状态的初步研究
2016/11/09 Python
python 并发编程 多路复用IO模型详解
2019/08/20 Python
new_zeros() pytorch版本的转换方式
2020/02/18 Python
Python3如何使用多线程升程序运行速度
2020/08/11 Python
Python实现爬取网页中动态加载的数据
2020/08/17 Python
Python中Qslider控件实操详解
2021/02/20 Python
什么是Oracle的后台进程background processes?都有哪些后台进程?
2012/04/26 面试题
中医药大学毕业生自荐信
2013/11/08 职场文书
个人素质的自我评价分享
2013/12/16 职场文书
商场父亲节活动方案
2014/08/27 职场文书
计划生育责任书
2015/05/09 职场文书
正规借条模板
2015/05/26 职场文书
MySQL数据库配置信息查看与修改方法详解
2022/06/25 MySQL