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 相关文章推荐
从新浪弄下来的全屏广告代码 与使用说明
Mar 15 Javascript
Jquery实现带动画效果的经典二级导航菜单
Mar 22 Javascript
浅谈JavaScript之事件绑定
Jul 08 Javascript
javaScript如何生成xmlhttp
Dec 16 Javascript
jQuery使用post方法提交数据实例
Mar 25 Javascript
浅析Javascript匿名函数与自执行函数
Feb 06 Javascript
js随机生成一个验证码
Jun 01 Javascript
你应该知道的几类npm依赖包管理详解
Oct 06 Javascript
MUI 实现侧滑菜单及其主体部分上下滑动的方法
Jan 25 Javascript
postman自定义函数实现 时间函数的思路详解
Apr 17 Javascript
150行代码带你实现微信小程序中的数据侦听
May 17 Javascript
vue element和nuxt的使用技巧分享
Jan 14 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
php生成静态文件的多种方法分享
2012/07/17 PHP
PHP删除目录及目录下所有文件的方法详解
2013/06/06 PHP
PHP中执行cmd命令的方法
2014/10/11 PHP
ajax+php实现无刷新验证手机号的实例
2017/12/22 PHP
CMSPRESS 10行代码搞定 PHP无限级分类2
2018/03/30 PHP
laravel框架路由分组,中间件,命名空间,子域名,路由前缀实例分析
2020/02/18 PHP
静态的动态续篇之来点XML
2006/08/15 Javascript
javascript延时重复执行函数 lLoopRun.js
2007/06/29 Javascript
javascript 避免闭包引发的问题
2009/03/17 Javascript
HTML上传控件取消选择
2013/03/06 Javascript
javascript类型转换示例
2014/04/29 Javascript
用Jquery.load载入页面后样式没了页面混乱的解决方法
2014/10/20 Javascript
jQuery函数map()和each()介绍及异同点分析
2014/11/08 Javascript
yui3的AOP(面向切面编程)和OOP(面向对象编程)
2015/05/01 Javascript
javascript检查浏览器是否已经启用XX功能
2015/07/10 Javascript
JavaScript学习笔记之ES6数组方法
2016/03/25 Javascript
JavaScript表单焦点自动切换代码
2016/07/24 Javascript
JS高仿抛物线加入购物车特效实现代码
2017/02/20 Javascript
vue axios用法教程详解
2017/07/23 Javascript
ES6使用Set数据结构实现数组的交集、并集、差集功能示例
2017/10/31 Javascript
vue 注册组件的使用详解
2018/05/05 Javascript
从0到1学习JavaScript编写贪吃蛇游戏
2020/07/28 Javascript
vue+echarts实现中国地图流动效果(步骤详解)
2021/01/27 Vue.js
Python 确定多项式拟合/回归的阶数实例
2018/12/29 Python
pandas通过字典生成dataframe的方法步骤
2019/07/23 Python
如何利用Python开发一个简单的猜数字游戏
2019/09/22 Python
python如何将两个txt文件内容合并
2019/10/18 Python
python列表推导和生成器表达式知识点总结
2020/01/10 Python
英语专业毕业生自荐信
2013/10/28 职场文书
个人简历自荐信
2013/12/05 职场文书
家居饰品店创业计划书
2014/01/31 职场文书
模具专业毕业推荐信
2014/03/08 职场文书
初三学生个人自我评定
2014/04/06 职场文书
团员个人年度总结
2015/02/26 职场文书
音乐之声观后感
2015/06/04 职场文书
深度学习详解之初试机器学习
2021/04/14 Python