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 相关文章推荐
jQuery使用手册之 事件处理
Mar 24 Javascript
JS 两日期相减,获得天数的小例子(兼容IE,FF)
Jul 01 Javascript
web css实现整站样式互相切换
Oct 29 Javascript
jquery的each方法使用示例分享
Mar 25 Javascript
浅谈javascript中call()、apply()、bind()的用法
Apr 20 Javascript
Jquery注册事件实现方法
May 18 Javascript
jQuery模仿阿里云购买服务器选择购买时间长度的代码
Apr 29 Javascript
详解Vue.js 2.0 如何使用axios
Apr 21 Javascript
js实现扫雷小程序的示例代码
Sep 27 Javascript
基于js 字符串indexof与search方法的区别(详解)
Dec 04 Javascript
JS实现横向轮播图(初级版)
Jun 24 Javascript
在vue中实现echarts随窗体变化
Jul 27 Javascript
微信小程序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
通过具体程序来理解PHP里面的抽象类
2010/01/28 PHP
基于magic_quotes_gpc与magic_quotes_runtime的区别与使用介绍
2013/04/22 PHP
PHP二维数组矩形转置实例
2016/07/20 PHP
PHP简单检测网址是否能够正常打开的方法
2016/09/04 PHP
PHP实现的防止跨站和xss攻击代码【来自阿里云】
2018/01/29 PHP
解决laravel5中auth用户登录其他页面获取不到登录信息的问题
2019/10/08 PHP
深入理解javascript中return的作用
2013/12/30 Javascript
JavaScript bold方法入门实例(把指定文字显示为粗体)
2014/10/17 Javascript
.NET微信公众号开发之创建自定义菜单
2015/07/16 Javascript
javascript中对变量类型的判断方法
2015/08/09 Javascript
js+css实现有立体感的按钮式文字竖排菜单效果
2015/09/01 Javascript
谈谈JavaScript自定义回调函数
2015/10/18 Javascript
一不小心就做错的JS闭包面试题
2015/11/25 Javascript
js随机生成26个大小写字母
2016/02/12 Javascript
创建一个类Person的简单实例
2016/05/17 Javascript
jQuery过滤选择器用法示例
2016/09/12 Javascript
webpack实现热更新(实施同步刷新)
2017/07/28 Javascript
jQuery EasyUI开发技巧总结
2017/09/26 jQuery
JavaScript实现读取与输出XML文件数据的方法示例
2018/06/05 Javascript
JavaScript创建表格的方法
2020/04/13 Javascript
Python学习笔记整理3之输入输出、python eval函数
2015/12/14 Python
python斐波那契数列的计算方法
2018/09/27 Python
基于Python对数据shape的常见操作详解
2018/12/25 Python
Python脚本按照当前日期创建多级目录
2019/03/01 Python
Chantelle仙黛尔内衣美国官网:法国第一品牌内衣
2018/07/26 全球购物
台湾时尚彩瞳专门店:imeime
2019/08/16 全球购物
Rentalcars.com中国:世界上最大的在线汽车租赁服务
2019/08/22 全球购物
护士自我鉴定
2013/10/23 职场文书
公交公司毕业生求职信
2014/02/15 职场文书
财务会计自荐信范文
2014/02/21 职场文书
医学求职自荐信
2014/06/21 职场文书
小学生国庆节演讲稿
2014/09/05 职场文书
护士心得体会范文
2016/01/25 职场文书
《颐和园》教学反思
2016/02/19 职场文书
pandas中DataFrame检测重复值的实现
2021/05/26 Python
深入理解java.lang.String类的不可变性
2021/06/27 Java/Android