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 相关文章推荐
EasySlider 基于jQuery功能强大简单易用的滑动门插件
Jun 11 Javascript
离开页面时检测表单元素是否被修改,提示保存的js代码
Aug 25 Javascript
Jquery中使用show()与hide()方法动画显示和隐藏图片
Oct 08 Javascript
jQuery ajax应用总结
Jun 02 Javascript
jQuery解析XML 详解及方法总结
Sep 28 Javascript
微信小程序自定义组件
Aug 16 Javascript
jQuery获取复选框选中的当前行的某个字段的值
Sep 15 jQuery
微信小程序中使用ECharts 异步加载数据实现图表功能
Jul 13 Javascript
vue多次循环操作示例
Feb 08 Javascript
JavaScript函数定义方法实例详解
Mar 05 Javascript
layui多图上传实现删除功能的例子
Sep 23 Javascript
js里面的变量范围分享
Jul 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
ip签名探针
2006/10/09 PHP
使用adodb lite解决问题
2006/12/31 PHP
PHP 变量的定义方法
2010/01/26 PHP
windows下升级PHP到5.3.3的过程及注意事项
2010/10/12 PHP
php下Memcached入门实例解析
2015/01/05 PHP
一组JS创建和操作表格的函数集合
2009/05/07 Javascript
javascript中负数算术右移、逻辑右移的奥秘探索
2013/10/17 Javascript
jQuery照片伸缩效果不影响其他元素的布局
2014/05/09 Javascript
jQuery常用数据处理方法小结
2015/02/20 Javascript
jQuery实现统计输入文字个数的方法
2015/03/11 Javascript
微信小程序 下拉菜单的实现
2017/04/06 Javascript
jQuery插件FusionCharts绘制2D环饼图效果示例【附demo源码】
2017/04/10 jQuery
JS 组件系列之 bootstrap treegrid 组件封装过程
2017/04/28 Javascript
angular实现IM聊天图片发送实例
2017/05/08 Javascript
JavaScript提升机制Hoisting详解
2019/10/23 Javascript
js生成1到100的随机数最简单的实现方法
2020/02/07 Javascript
解决vant框架做H5时踩过的坑(下拉刷新、上拉加载等)
2020/11/11 Javascript
[05:06]TI4西雅图DOTA2前线报道 海涛密探LGD训练
2014/07/09 DOTA
[42:27]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#2Fnatic VS OG第三局
2016/03/05 DOTA
python使用百度翻译进行中翻英示例
2014/04/14 Python
快速入手Python字符编码
2016/08/03 Python
Python+selenium点击网页上指定坐标的实例
2019/07/05 Python
python找出列表中大于某个阈值的数据段示例
2019/11/24 Python
在django中自定义字段Field详解
2019/12/03 Python
Python列表list操作相关知识小结
2020/01/29 Python
pycharm第三方库安装失败的问题及解决经验分享
2020/05/09 Python
Sublime Text3最新激活注册码分享适用2020最新版 亲测可用
2020/11/12 Python
HelloFresh澳大利亚:订购你的美味食品盒、健康餐食
2018/03/28 全球购物
SISLEY希思黎官方旗舰店:享誉全球的奢华植物美容品牌
2018/04/25 全球购物
房产销售经理职责
2013/12/20 职场文书
兰兰过桥教学反思
2014/02/08 职场文书
决心书标准格式
2014/03/11 职场文书
公司授权委托书样本
2014/09/15 职场文书
第一书记观后感
2015/06/08 职场文书
MySQL5.7并行复制原理及实现
2021/06/03 MySQL
Python实现天气查询软件
2021/06/07 Python