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 相关文章推荐
10个基于jQuery或JavaScript的WYSIWYG 编辑器整理
May 06 Javascript
jquery获取多个checkbox的值异步提交给php
Jul 07 Javascript
如何利用JS通过身份证号获取当事人的生日、年龄、性别
Jan 22 Javascript
Angular 理解module和injector,即依赖注入
Sep 07 Javascript
微信小程序  modal详解及实例代码
Nov 09 Javascript
Javascript中return的使用与闭包详解
Jan 11 Javascript
ionic 3.0+ 项目搭建运行环境的教程
Aug 09 Javascript
Vue中定义全局变量与常量的各种方式详解
Aug 23 Javascript
Vuejs 页面的区域化与组件封装的实现
Sep 11 Javascript
使用electron将vue-cli项目打包成exe的方法
Sep 29 Javascript
微信小程序之 catalog 切换实现解析
Sep 12 Javascript
怎么理解wx.navigateTo的events参数使用详情
May 18 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中smarty变量修饰用法实例分析
2015/06/11 PHP
PHP模拟QQ登录的方法
2015/07/29 PHP
php正则表达式验证(邮件地址、Url地址、电话号码、邮政编码)
2016/03/14 PHP
Laravel手动返回错误码示例
2019/10/22 PHP
Javascript 实现的数独解题算法网页实例
2013/10/15 Javascript
css配合jquery美化 select
2013/11/29 Javascript
PHPExcel中的一些常用方法汇总
2015/01/23 Javascript
jQuery使用attr()方法同时设置多个属性值用法实例
2015/03/26 Javascript
JavaScript改变CSS样式的方法汇总
2015/05/07 Javascript
总结js中的一些兼容性易错的问题
2017/12/18 Javascript
JavaScript中的一些实用小技巧总结
2019/04/07 Javascript
自定义Vue组件打包、发布到npm及使用教程
2019/05/22 Javascript
Vue项目实现简单的权限控制管理功能
2019/07/17 Javascript
Taro UI框架开发小程序实现左滑喜欢右滑不喜欢效果的示例代码
2020/05/18 Javascript
vue3.0 自适应不同分辨率电脑的操作
2021/02/06 Vue.js
[02:17]快乐加倍!DOTA2食人魔魔法师至宝+迎霜节活动上线
2019/12/22 DOTA
Python中的startswith和endswith函数使用实例
2014/08/25 Python
python端口扫描系统实现方法
2014/11/19 Python
仅用50行Python代码实现一个简单的代理服务器
2015/04/08 Python
简单实现python画圆功能
2018/01/25 Python
深入分析python中整型不会溢出问题
2018/06/18 Python
使用python读取.text文件特定行的数据方法
2019/01/28 Python
详解python中的hashlib模块的使用
2019/04/22 Python
用Python获取摄像头并实时控制人脸的实现示例
2019/07/11 Python
关于Python 中的时间处理包datetime和arrow的方法详解
2020/03/19 Python
Python图像识别+KNN求解数独的实现
2020/11/13 Python
手把手教你用纯css3实现轮播图效果实例
2017/05/04 HTML / CSS
html5 Canvas画图教程(7)—canvas里画曲线之quadraticCurveTo方法
2013/01/09 HTML / CSS
浅谈移动端网页图片预加载方案
2018/11/05 HTML / CSS
JD Sports荷兰:英国领先的运动时尚零售商
2020/03/13 全球购物
生物化工专业个人自荐信
2013/09/26 职场文书
日语专业毕业生求职信
2013/12/04 职场文书
英语道歉信范文
2014/01/09 职场文书
关爱留守儿童标语
2014/06/18 职场文书
信息合作协议书
2014/10/09 职场文书
导游词之西递宏村
2019/12/10 职场文书