vue实现数据控制视图的原理解析


Posted in Javascript onJanuary 07, 2020

这篇主要讲的就是vue很重要的一块知识点,双向数据绑定是如何实现的。一开始看这一块的内容的时候比较迷茫,迷茫在以下几个点:

  1. 这块内容该从哪边入手
  2. 数据变化是如何驱动视图层更新的
  3. 做题深化知识点

从哪边着手去看响应式原理

我这边提供三个方向,从这三个方向,你都可以看到watcher的使用,然后watcher的使用过程中,会掺杂到observer以及dep,然后以点带面,对整体进行梳理

初始化的render流程去看

在lifecycle这个文件中的mountComponent这个方法里,创建了一个watcher。代码如下:

new Watcher(vm, updateComponent, noop, {
 before () {
  if (vm._isMounted && !vm._isDestroyed) {
  callHook(vm, 'beforeUpdate')
  }
 }
}, true /* isRenderWatcher */)

可以透过这个传参,梳理出整一个

  • 从watch的角度去看
  • 从computed的角度去看

数据变化是如何驱动视图层更新的

这个问题其实可以分两个方面去看:

如何知道数据变化了

如何知道某一块视图和数据有关,并更新他 如何知道数据变化了

答案:数据劫持

数据劫持的两种方式

Object.defineProperty
proxy

Vue3.0中的数据劫持是用proxy来实现的,目前阅读的源码中,都是以 Object.defineProperty 这种方式来实现的。

如何知道某一块视图和数据有关,并更新他

答案:依赖收集以及订阅更新

详细解读过程:用图告诉你响应式原理

这里仅用一个简单的例子和图,来明确一下整个流程

<div id="app">
 {{ message }}
 {{ message1 }}
 <input type="text" v-model="message">
 <div @click="changeMessage">改变message</div>  
</div>
var app = new Vue({
 el: '#app',
 data: {
  message: '1',
  message1: '2',
 },
 methods: {
  changeMessage() {
   this.message = '2'
  }
 },
 watch: {
  message: function(val) {
   this.message1 = val
  }
 }
})

依赖收集流程图

vue实现数据控制视图的原理解析

依赖收集的最终结果:

vue实现数据控制视图的原理解析

订阅更新流程图:

vue实现数据控制视图的原理解析

做题深化知识点

题目如下:

1、简述Vue的响应式原理

2、计算属性和watch的区别

3、Vue中给data中的对象属性添加一个新的属性时会发生什么,如何解决?

对于第一和第二在这里就不花篇幅去说明。

Vue中给data中的对象属性添加一个新的属性时会发生什么,如何解决?

我们在做业务的时候经常会遇到这样的情况,我举一个简单的例子:

<template>
 <div>
 <ul>
  <li v-for="value in obj" :key="value">
  {{value}}
  </li>
 </ul>
 <button @click="addObjB">添加obj.b</button>
 </div>
</template>
<script>
export default {
 data () {
 return {
  obj: {
  a: 'obj.a'
  }
 }
 },
 methods: {
 addObjB () {
  this.obj.b = 'obj.b'
  console.log(this.obj)
 }
 }
}
</script>
<style></style>

依赖收集流程:

vue实现数据控制视图的原理解析

从中我们可以发现,renderWatch是有收集 Dep(obj)Dep(Obj.a) 的,但是当我们改变Obj的时候,并没有触发视图的更新。因为我们在改变obj的值的时候,并没有去触发Dep(obj)。

产生问题的本质原因:

1、vue会在state.js文件的initData的方法中,将data属性中的每一个key都变成响应式属性。

2、视图在渲染过程中,会将renderWatcher收集到用到的值的dep中,方便依赖更新(不懂的在回过去看一下依赖收集流程)

3、当你额外添加一个属性的时候,该属性并不是响应式属性。

那如何去改变:

addObjB () {
 // this.obj.b = 'obj.b'
 this.$set(this.obj, 'b', 'obj.b')
 console.log(this.obj)
}

总结

这篇文章是年度总结的开篇,后续会继续总结初始化部分、render部分和patch部分。希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
Ucren Virtual Desktop V2.0
Nov 07 Javascript
插件:检测javascript的内存泄漏
Mar 04 Javascript
JavaScript 盒模型 尺寸深入理解
Dec 31 Javascript
JavaScript数组常用操作技巧汇总
Nov 17 Javascript
封装好的一个万能检测表单的方法
Jan 21 Javascript
js实现可旋转的立方体模型
Oct 16 Javascript
javaScript语法总结
Nov 25 Javascript
vue给input file绑定函数获取当前上传的对象完美实现方法
Dec 15 Javascript
微信小程序仿美团城市选择
Jun 06 Javascript
layui输入框只允许输入中文且判断长度的例子
Sep 18 Javascript
如何使用gpu.js改善JavaScript的性能
Dec 01 Javascript
vue使用watch监听属性变化
Apr 30 Vue.js
微信小程序wx.navigateTo方法里的events参数使用详情及场景
Jan 07 #Javascript
详解微信小程序之提高应用速度小技巧
Jan 07 #Javascript
小程序跨页面交互的作用与方法详解
Jan 07 #Javascript
JavaScript实现联动菜单特效
Jan 07 #Javascript
JS实现电商商品展示放大镜特效
Jan 07 #Javascript
JS实现字体背景跑马灯
Jan 06 #Javascript
JS实现音乐钢琴特效
Jan 06 #Javascript
You might like
在字符串中把网址改成超级链接
2006/10/09 PHP
Base64在线编码解码实现代码 演示与下载
2011/01/08 PHP
php流量统计功能的实现代码
2012/09/29 PHP
如何用php获取文件名后缀
2013/06/09 PHP
PHP内核探索:哈希表碰撞攻击原理
2015/07/31 PHP
详解Yii2.0使用AR联表查询实例
2017/06/16 PHP
javascript 单例/单体模式(Singleton)
2011/04/07 Javascript
ExtJs中gridpanel分组后组名排序实例代码
2013/12/02 Javascript
解决Jquery鼠标经过不停滑动的问题
2014/03/03 Javascript
node.js WEB开发中图片验证码的实现方法
2014/06/03 Javascript
Jquery动态替换div内容及动态展示的方法
2015/01/23 Javascript
javascript中new关键字详解
2015/12/14 Javascript
原生JS实现图片轮播与淡入效果的简单实例
2016/08/21 Javascript
AngularJS中$http的交互问题
2017/03/29 Javascript
vue引入新版 vue-awesome-swiper插件填坑问题
2018/01/25 Javascript
jQuery滚动条美化插件nicescroll简单用法示例
2018/04/18 jQuery
微信小程序学习笔记之登录API与获取用户信息操作图文详解
2019/03/29 Javascript
微信小程序如何加载数据库真实数据的实现
2020/03/04 Javascript
JavaScript检测是否开启了控制台(F12调试工具)
2020/10/02 Javascript
详解Python验证码识别
2016/01/25 Python
pandas 根据列的值选取所有行的示例
2018/11/07 Python
如何通过python实现人脸识别验证
2020/01/17 Python
利用 Python ElementTree 生成 xml的实例
2020/03/06 Python
TensorFlow tf.nn.conv2d_transpose是怎样实现反卷积的
2020/04/20 Python
澳大利亚在线奢侈品时尚零售平台:Azura Runway
2021/01/13 全球购物
武汉世纪畅想数字传播有限公司.NET笔试题
2014/07/22 面试题
英语专业应届生求职信范文
2013/11/15 职场文书
项目合作协议书
2014/04/16 职场文书
元旦晚会活动总结
2014/07/09 职场文书
2014年全国爱牙日宣传活动方案
2014/09/21 职场文书
2014年保洁员工作总结
2014/11/19 职场文书
大学生实习介绍信
2015/05/05 职场文书
学生病假条怎么写
2015/08/17 职场文书
少儿励志名言(80句)
2019/08/14 职场文书
Python基本的内置数据类型及使用方法
2022/04/13 Python
Alexa停服!网站排名将何去何从?目前还没有替代品。
2022/04/15 杂记