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 相关文章推荐
mapper--图片热点区域高亮组件官方站点
Dec 22 Javascript
JavaScript中的匀速运动和变速(缓冲)运动详细介绍
Nov 11 Javascript
js获取当前月的第一天和最后一天的小例子
Nov 18 Javascript
网页实时显示服务器时间和javscript自运行时钟
Jun 09 Javascript
js实现鼠标滑过文字链接色彩变化的效果
May 06 Javascript
谈谈我对JavaScript DOM事件的理解
Dec 18 Javascript
js实现文本框输入文字个数限制代码
Dec 25 Javascript
Bootstrap导航条学习使用(二)
Feb 08 Javascript
详解基于Vue cli生成的Vue项目的webpack4升级
Jun 19 Javascript
react native 获取地理位置的方法示例
Aug 28 Javascript
js实现数字滚动特效
Dec 16 Javascript
JavaScript如何优化逻辑判断代码详解
Jun 08 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
深入解析phpCB批量转换的代码示例
2013/06/27 PHP
linux系统下php安装mbstring扩展的二种方法
2014/01/20 PHP
WordPress中获取页面链接和标题的相关PHP函数用法解析
2015/12/17 PHP
编写PHP脚本清除WordPress头部冗余代码的方法讲解
2016/03/01 PHP
PHP扩展Swoole实现实时异步任务队列示例
2019/04/13 PHP
Javascript调用XML制作连动下拉列表框
2006/06/25 Javascript
javascript getElementsByClassName 和js取地址栏参数
2010/01/02 Javascript
类似GMAIL的Ajax信息反馈显示
2010/02/16 Javascript
Javascript 匿名函数及其代码模式原理
2010/03/19 Javascript
JQuery中getJSON的使用方法
2010/12/13 Javascript
jquery的flexigrid无法显示数据提示获取到数据
2013/07/19 Javascript
浅谈jQuery异步对象(XMLHttpRequest)
2014/11/17 Javascript
jQuery中slideUp()方法用法分析
2014/12/24 Javascript
javascript框架设计之浏览器的嗅探和特征侦测
2015/06/23 Javascript
基于jQuery实现仿51job城市选择功能实例代码
2016/03/02 Javascript
Vuex和前端缓存的整合策略详解
2017/05/09 Javascript
微信小程序实现下拉刷新和轮播图效果
2017/11/21 Javascript
react实现同页面三级跳转路由布局
2019/09/26 Javascript
Layui带搜索的下拉框的使用以及动态数据绑定方法
2019/09/28 Javascript
Vue-axios-post数据后端接不到问题解决
2020/01/09 Javascript
微信小程序开发中var that =this的用法详解
2020/01/18 Javascript
python的几种开发工具介绍
2007/03/07 Python
Python装饰器使用示例及实际应用例子
2015/03/06 Python
解决Python获取字典dict中不存在的值时出错问题
2018/10/17 Python
python爬虫获取新浪新闻教学
2018/12/23 Python
python安装pywin32clipboard的操作方法
2019/01/24 Python
三星加拿大官方网上商店:Samsung CA
2020/12/18 全球购物
技校教师求职简历的自我评价
2013/10/20 职场文书
你的创业计划书怎样才能打动风投
2014/02/06 职场文书
公证委托书格式
2014/09/13 职场文书
2015年中秋节主持词
2015/07/30 职场文书
2016三八妇女节慰问信
2015/11/30 职场文书
centos8安装MongoDB的详细过程
2021/10/24 MongoDB
js 数组 fill() 填充方法
2021/11/02 Javascript
Win11 Build 21996.1 Dev版怎么样? win11系统截图欣赏
2021/11/21 数码科技
Oracle 多表查询基本语法实例
2022/04/18 Oracle