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 使用个人心得
Feb 26 Javascript
Extjs EditorGridPanel中ComboBox列的显示问题
Jul 04 Javascript
动态创建样式表在各浏览器中的差异测试代码
Sep 13 Javascript
ExtJs使用总结(非常详细)
Mar 22 Javascript
一个简单的瀑布流效果(主体形式自写)
May 27 Javascript
jQuery计算textarea中文字数(剩余个数)的小程序
Nov 28 Javascript
基于jQuery实现的QQ表情插件
Aug 25 Javascript
漂亮实用的页面loading(加载)封装代码
Feb 03 Javascript
Node.js环境下Koa2添加travis ci持续集成工具的方法
Jun 19 Javascript
knockoutjs模板实现树形结构列表
Jul 31 Javascript
vue项目中实现的微信分享功能示例
Jan 21 Javascript
Vue.js下拉菜单组件使用方法详解
Oct 19 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
dedecms系统的广告设置代码 基础版本
2010/04/09 PHP
php上传apk后自动提取apk包信息的使用(示例下载)
2013/04/26 PHP
深入理解JavaScript系列(8) S.O.L.I.D五大原则之里氏替换原则LSP
2012/01/15 Javascript
window.location.href = window.location.href 跳转无反应 a超链接onclick事件写法
2013/08/21 Javascript
父页面显示遮罩层弹出半透明状态的dialog
2014/03/04 Javascript
javascript框架设计读书笔记之模块加载系统
2014/12/02 Javascript
JavaScript实现MIPS乘法模拟的方法
2015/04/17 Javascript
使用JavaScript脚本无法直接改变Asp.net中Checkbox控件的Enable属性的解决方法
2015/09/16 Javascript
利用vscode编写vue的简单配置详解
2017/06/17 Javascript
mac上配置Android环境变量的方法
2018/07/08 Javascript
微信小程序 简易计算器实现代码实例
2019/09/02 Javascript
小程序实现日历左右滑动效果
2019/10/21 Javascript
JavaScript This指向问题详解
2019/11/25 Javascript
[02:37]2018DOTA2亚洲邀请赛赛前采访-EG篇
2018/04/03 DOTA
Python实现删除Android工程中的冗余字符串
2015/01/19 Python
Python工程师面试题 与Python Web相关
2016/01/14 Python
python实现按行切分文本文件的方法
2016/04/18 Python
对python多线程与global变量详解
2018/11/09 Python
python elasticsearch从创建索引到写入数据的全过程
2019/08/04 Python
用Pytorch训练CNN(数据集MNIST,使用GPU的方法)
2019/08/19 Python
python使用Matplotlib改变坐标轴的默认位置
2019/10/18 Python
python将数组n等分的实例
2019/12/02 Python
解决Pytorch训练过程中loss不下降的问题
2020/01/02 Python
Jupyter notebook 远程配置及SSL加密教程
2020/04/14 Python
Django Path转换器自定义及正则代码实例
2020/05/29 Python
keras绘制acc和loss曲线图实例
2020/06/15 Python
Pandas对每个分组应用apply函数的实现
2020/12/13 Python
PyChon中关于Jekins的详细安装(推荐)
2020/12/28 Python
Python实现微信表情包炸群功能
2021/01/28 Python
KEEN美国官网:美国人气户外休闲鞋品牌
2021/03/09 全球购物
一些.net面试题
2014/10/06 面试题
学习十八大的心得体会
2014/09/12 职场文书
授权委托书公证
2014/09/14 职场文书
开国大典观后感
2015/06/04 职场文书
python基础之函数的定义和调用
2021/10/24 Python
Python实现猜拳与猜数字游戏的方法详解
2022/04/06 Python