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 相关文章推荐
jQuery 表单验证扩展(四)
Oct 20 Javascript
JS Range HTML文档/文字内容选中、库及应用介绍
May 12 Javascript
javascript中简单的进制转换代码实例
Oct 26 Javascript
js仿黑客帝国字母掉落效果代码分享
Nov 08 Javascript
jQuery电话号码验证实例
Jan 05 Javascript
详解angularjs结合pagination插件实现分页功能
Feb 10 Javascript
Angular 通过注入 $location 获取与修改当前页面URL的实例
May 31 Javascript
vue 简单自动补全的输入框的示例
Mar 12 Javascript
Redux实现组合计数器的示例代码
Jul 04 Javascript
node.js实现为PDF添加水印的示例代码
Dec 05 Javascript
Vue父子传递实例讲解
Feb 14 Javascript
vscode 配置vue+vetur+eslint+prettier自动格式化功能
Mar 23 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
php使用Jpgraph绘制饼状图的方法
2015/06/10 PHP
通过chrome浏览器控制台(Console)进行PHP Debug的方法
2016/10/19 PHP
js null,undefined,字符串小结
2010/08/21 Javascript
利用JS实现浏览器的title闪烁
2013/07/08 Javascript
JS实现控制表格行文本对齐的方法
2015/03/30 Javascript
animate 实现滑动切换效果【实例代码】
2016/05/05 Javascript
JS读取XML文件数据并以table形式显示数据的方法(兼容IE与火狐)
2016/06/02 Javascript
jquery实现tab键进行选择后enter键触发click行为
2017/03/29 jQuery
JS 插件dropload下拉刷新、上拉加载使用小结
2017/04/13 Javascript
vue loadmore组件上拉加载更多功能示例代码
2017/07/19 Javascript
JS实现快速比较两个字符串中包含有相同数字的方法
2017/09/11 Javascript
微信小程序实现笑脸评分功能
2018/11/03 Javascript
如何使用electron-builder及electron-updater给项目配置自动更新
2018/12/24 Javascript
使用vue-cli脚手架工具搭建vue-webpack项目
2019/01/14 Javascript
Vue点击切换Class变化,实现Active当前样式操作
2020/07/17 Javascript
[44:26]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#4EG VS Fnatic第二局
2016/03/03 DOTA
python实现批量监控网站
2016/09/09 Python
python 实现自动远程登陆scp文件实例代码
2017/03/13 Python
Python常见加密模块用法分析【MD5,sha,crypt模块】
2017/05/24 Python
Python新手如何理解循环加载模块
2020/05/29 Python
使用Keras加载含有自定义层或函数的模型操作
2020/06/10 Python
无需压缩软件,用python帮你操作压缩包
2020/08/17 Python
Scrapy爬虫文件批量运行的实现
2020/09/30 Python
python脚本使用阿里云slb对恶意攻击进行封堵的实现
2021/02/04 Python
巴西男士个人护理产品商店:SHOP4MEN
2017/08/07 全球购物
英国女士家居服网站:hush
2017/08/09 全球购物
美国正宗奢华复古手袋、珠宝及配饰网站:What Goes Around Comes Around
2018/07/21 全球购物
美国唇部护理专家:Sara Happ
2019/06/19 全球购物
一份Java笔试题
2012/02/21 面试题
市场营销职业生涯规划书范文
2014/01/12 职场文书
音乐学专业求职信
2014/07/22 职场文书
十一国庆节“向国旗敬礼”主题班会活动方案
2014/09/27 职场文书
学校领导班子四风问题整改意见
2014/10/02 职场文书
停水通知
2015/04/16 职场文书
起诉书格式范文
2015/05/20 职场文书
让生命充满爱观后感
2015/06/08 职场文书