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 相关文章推荐
跟随鼠标旋转的文字
Nov 30 Javascript
原生javascript实现获取指定元素下所有后代元素的方法
Oct 28 Javascript
AngularJS + Node.js + MongoDB开发的基于高德地图位置的通讯录
Jan 02 Javascript
JS实现新浪博客左侧的Blog管理菜单效果代码
Oct 22 Javascript
JS实现不使用图片仿Windows右键菜单效果代码
Oct 22 Javascript
Knockout自定义绑定创建方法
Dec 26 Javascript
JavaScript的设计模式经典之代理模式
Feb 24 Javascript
jQuery实现TAB选项卡切换特效简单演示
Mar 04 Javascript
实例讲解JavaScript的Backbone.js框架中的View视图
May 05 Javascript
Google 地图API资料整理及详细介绍
Aug 06 Javascript
基于jQuery实现定位导航位置效果
Nov 15 jQuery
JSONObject与JSONArray使用方法解析
Sep 28 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
DC动画电影《黑暗正义联盟》曝预告 5月5日上线数字平台
2020/04/09 欧美动漫
浅谈PHP与C#的值类型指向区别的详解
2013/05/21 PHP
ThinkPHP模型详解
2015/07/27 PHP
使用PHP下载CSS文件中的所有图片【几行代码即可实现】
2016/12/14 PHP
Win10 下安装配置IIS + MySQL + nginx + php7.1.7
2017/08/04 PHP
PHP基础之输出缓冲区基本概念、原理分析
2019/06/19 PHP
javascript入门·动态的时钟,显示完整的一些方法,新年倒计时
2007/10/01 Javascript
一些经常会用到的Javascript检测函数
2010/05/31 Javascript
jQuery最佳实践完整篇
2011/08/20 Javascript
基于javascript实现窗口抖动效果
2016/01/03 Javascript
JavaScript获取当前运行脚本文件所在目录的方法
2016/02/03 Javascript
JS封装的三级联动菜单(使用时只需要一行js代码)
2016/10/24 Javascript
javascript实现一个网页加载进度loading
2017/01/04 Javascript
socket.io学习教程之基础介绍(一)
2017/04/29 Javascript
NodeJs搭建本地服务器之使用手机访问的实例讲解
2018/05/12 NodeJs
vue 优化CDN加速的方法示例
2018/09/19 Javascript
Vue实现回到顶部和底部动画效果
2019/07/31 Javascript
js通过循环多张图片实现动画效果
2019/12/19 Javascript
JS端基于download.js实现图片、视频时直接下载而不是打开预览
2020/05/09 Javascript
[01:25]2014DOTA2国际邀请赛 zhou分析LGD比赛情况
2014/07/14 DOTA
[01:04]DOTA2上海特锦赛现场采访 FreeAgain遭众解说围攻
2016/03/25 DOTA
[01:02:48]2018DOTA2亚洲邀请赛小组赛 A组加赛 Newbee vs Liquid
2018/04/03 DOTA
Python跳出循环语句continue与break的区别
2014/08/25 Python
PYTHON压平嵌套列表的简单实现
2016/06/08 Python
Python实现简单网页图片抓取完整代码实例
2017/12/15 Python
对pandas读取中文unicode的csv和添加行标题的方法详解
2018/12/12 Python
PyQt5重写QComboBox的鼠标点击事件方法
2019/06/25 Python
python安装第三方库如xlrd的方法
2020/10/31 Python
CSS3下的渐变文字效果实现示例
2018/03/02 HTML / CSS
高中三年学习生活的自我评价
2013/10/10 职场文书
期末自我鉴定
2014/02/02 职场文书
大学生找工作求职信
2014/07/09 职场文书
后勤管理员岗位职责
2014/08/27 职场文书
2014年教务工作总结
2014/12/03 职场文书
优秀家长事迹材料(2016推荐版)
2016/02/29 职场文书
python代码实现备忘录案例讲解
2021/07/26 Python