vue2.0 之 深入响应式原理

时间:2022-09-26 16:48:52
实例demo

<div id="app">
<span>{{a}}</span>
<input type="text" v-model="a">
<span>{{b}}</span>
<input type="text" v-model="b"> <span>{{k.b}}</span>
<input type="text" v-model="k.b"> <span>{{info.a}}</span>
<input type="text" v-model="info.a">
<span>{{info.b}}</span>
<input type="text" v-model="info.b"> 姓名:{{name}}<br>
年龄:{{age}}<br>
性别:{{info.sex}}<br>
说明:{{info.content}}
</div>
<script>
1、第一种情况
var vm = new Vue({
el: '#app',
data:{
a:1,
k: {}
}
}) // `vm.a` 是响应的vm.b = 2
// `vm.b` 是非响应的 // 使用 Vue.set(object, key, value) 方法将响应属性添加到 嵌套 的对象上, 不能加到data上面
// Vue.set(vm.k, 'b', 9)
// vm.$set 实例方法,这也是全局 Vue.set方法的别名
// this.$set(this.k,'b',2)
// 向已有对象上添加一些属性
// Object.assign() 或 _.extend() 方法来添加属性。但是,添加到对象上的新属性不会触发更新。在这种情况下可以创建一个新的对象,让它包含原对象的属性和新的属性
注意:第一种方式添加的属性是响应式,第二种是非响应式 2、第二种情况 var data = {
name: "脚本之家",
age: '3',
info: {
content: 'my name is test'
}
}
var vm = new Vue({
el:'#app',
data: data,
mounted: function () {
// Vue.set(data,'sex', '男') //错误❌
// 第一种方法
Vue.set(this.info,'sex', '男')
this.$set(this.info, 'sex', '男')
this.$set(this.info, 'content','what is this?')
// 第二种方法
//data = Object.assign({}, data, { c: 1, d: 2 }) //错误❌
this.info = Object.assign({}, this.info, { a: 1, b: 2 })
console.log(this.info)
}
});
// data.sex = '男' //警告⚠️ warn

一、变化追踪

把一个普通 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。Object.defineProperty 是仅 ES5 支持,且无法 shim 的特性,这也就是为什么 Vue 不支持 IE8 以及更低版本浏览器的原因。

用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。可通过vue-devtools 查看

每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

如图所示:

vue2.0 之 深入响应式原理

含义: 即在初次渲染的过程中就会调用对象属性的getter函数,然后getter函数通知wather对象将之声明为依赖,依赖之后,如果对象属性发生了变化,那么就会调用settter函数来通知watcher,watcher就会在重新渲染组件,以此来完成更新。

二、变化检测问题

受现代 JavaScript 的限制(以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

具体实例见 开篇的实例demo, 同时可参考 http://www.cnblogs.com/zhuzhenwei918/p/6893496.html

三、声明响应式属性

由于 Vue 不允许动态添加根级响应式属性,所以你必须在初始化实例前声明根级响应式属性,可以为一个空值

如果你在 data 选项中未声明 message,Vue 将警告你渲染函数在试图访问的属性不存在。

四、异步更新队列

Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会一次推入到队列中。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际(已去重的)工作。Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MutationObserver,如果执行环境不支持,会采用 setTimeout(fn, 0) 代替。

例如,当你设置 vm.someData = 'new value' ,该组件不会立即重新渲染。当刷新队列时,组件会在事件循环队列清空时的下一个“tick”更新。多数情况我们不需要关心这个过程,但是如果想在 DOM 状态更新后操作,为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。

具体实例见 nextTick 详解 http://www.cnblogs.com/136asdxxl/p/7291640.html

参考:http://www.cnblogs.com/zhuzhenwei918/p/6893496.html

vue2.0 之 深入响应式原理的更多相关文章

  1. Vue&period;2&period;0&period;5-深入响应式原理

    大部分的基础内容我们已经讲到了,现在讲点底层内容.Vue 最显著的一个功能是响应系统 -- 模型只是普通对象,修改它则更新视图.这会让状态管理变得非常简单且直观,不过理解它的原理以避免一些常见的陷阱也 ...

  2. Vue2源码解读 - 响应式原理及简单实现

    直接进入主题了,想必大家都知道实现vue响应式核心方法就是 Object.defineProperty,那就从它开始说 Object.defineProperty 缺点: 深度监听,需要递归到底,一次 ...

  3. Vue 2&period;0 与 Vue 3&period;0 响应式原理比较

    Vue 2.0 的响应式是基于Object.defineProperty实现的 当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 prop ...

  4. 浅谈vue响应式原理及发布订阅模式和观察者模式

    一.Vue响应式原理 首先要了解几个概念: 数据响应式:数据模型仅仅是普通的Javascript对象,而我们修改数据时,视图会进行更新,避免了繁琐的DOM操作,提高开发效率. 双向绑定:数据改变,视图 ...

  5. vue2&period;0与3&period;0响应式原理机制

    vue2.0响应式原理 - defineProperty 这个原理老生常谈了,就是拦截对象,给对象的属性增加set 和 get方法,因为核心是defineProperty所以还需要对数组的方法进行拦截 ...

  6. Vue2&period;x响应式原理

    一.回顾Vue响应式用法 ​ vue响应式,我们都很熟悉了.当我们修改vue中data对象中的属性时,页面中引用该属性的地方就会发生相应的改变.避免了我们再去操作dom,进行数据绑定. 二.Vue响应 ...

  7. &lbrack;切图仔救赎&rsqb;炒冷饭--在线手撸vue2响应式原理

    --图片来源vue2.6正式版本(代号:超时空要塞)发布时,尤雨溪推送配图. 前言 其实这个冷饭我并不想炒,毕竟vue3马上都要出来.我还在这里炒冷饭,那明显就是搞事情. 起因: 作为切图仔搬砖汪,长 ...

  8. Vue2 响应式原理

    我们经常用vue的双向绑定,改变data的某个属性值,vue就马上帮我们自动更新视图,下面我们看看原理. Object的响应式原理: 可以看到,其实核心就是把object的所有属性都加上getter. ...

  9. Vue源码--解读vue响应式原理

    原文链接:https://geniuspeng.github.io/2018/01/05/vue-reactivity/ Vue的官方说明里有深入响应式原理这一节.在此官方也提到过: 当你把一个普通的 ...

随机推荐

  1. Android组件化和插件化开发

    http://www.cnblogs.com/android-blogs/p/5703355.html 什么是组件化和插件化? 组件化开发就是将一个app分成多个模块,每个模块都是一个组件(Modul ...

  2. 匈牙利算法 DFS模板(了解度&plus;1)

    //算法核心是求最大匹配数 #include<bits/stdc++.h> #include<iostream> #include<cstdio> #include ...

  3. 利用PHPMailer 来完成PHP的邮件发送 &num;转载自:大菜鸟在云端&num;

    利用PHPMailer 来完成PHP的邮件发送 1.首先是下载PHPMailer http://code.google.com/a/apache-extras.org/p/phpmailer/ 2.解 ...

  4. 游戏贴图中常用术语《DC》的理解

    什么是DC呢? 在GDI中,DC(Device Context)是一个非常重要的概念. 有的书中,将DC翻译为设备描述表,也有的书中翻译为设备上下文. 但是这些翻译,无法在我们的头脑里有强烈的冲击,无 ...

  5. MySQL执行计划中key&lowbar;len详解

    (1).索引字段的附加信息:可以分为变长和定长数据类型讨论,当索引字段为定长数据类型,比如char,int,datetime,需要有是否为空的标记,这个标记需要占用1个字节:对于变长数据类型,比如:v ...

  6. 阿里云 通过YUM源安装nginx

    阿里云centOS-6.3-64位通过YUM源安装nginx 第一步:在 /etc/yum.repos.d/ 目录下,建立名叫nginx.repo的软件源配置文件.   文件 nginx.repo 的 ...

  7. Chrome扩展开发之四——核心功能的实现思路

    目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...

  8. BOM List demo

    select level level_id,        t.*   from (select msi1.segment1 farther_item,                msi1.inv ...

  9. Helix Streaming Server 简单配置

    双击桌面上新出现的"HelixServer"图标,正常的话应该如图9,不要关闭这个窗口. 双击"HelixServerAdministrator"图标,输入用户 ...

  10. 【bzoj3589】动态树 树链剖分&plus;树链的并

    题解: 树链剖分是显然的 问题在于求树链的并 比较简单的方法是 用线段树打标记覆盖,查询标记区间大小 Qlog^2n 代码: #include <bits/stdc++.h> using ...