vue2.0 之 深入响应式原理
实例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 重新计算,从而致使它关联的组件得以更新。
如图所示:

含义: 即在初次渲染的过程中就会调用对象属性的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 之 深入响应式原理的更多相关文章
- Vue.2.0.5-深入响应式原理
大部分的基础内容我们已经讲到了,现在讲点底层内容.Vue 最显著的一个功能是响应系统 -- 模型只是普通对象,修改它则更新视图.这会让状态管理变得非常简单且直观,不过理解它的原理以避免一些常见的陷阱也 ...
- Vue2源码解读 - 响应式原理及简单实现
直接进入主题了,想必大家都知道实现vue响应式核心方法就是 Object.defineProperty,那就从它开始说 Object.defineProperty 缺点: 深度监听,需要递归到底,一次 ...
- Vue 2.0 与 Vue 3.0 响应式原理比较
Vue 2.0 的响应式是基于Object.defineProperty实现的 当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 prop ...
- 浅谈vue响应式原理及发布订阅模式和观察者模式
一.Vue响应式原理 首先要了解几个概念: 数据响应式:数据模型仅仅是普通的Javascript对象,而我们修改数据时,视图会进行更新,避免了繁琐的DOM操作,提高开发效率. 双向绑定:数据改变,视图 ...
- vue2.0与3.0响应式原理机制
vue2.0响应式原理 - defineProperty 这个原理老生常谈了,就是拦截对象,给对象的属性增加set 和 get方法,因为核心是defineProperty所以还需要对数组的方法进行拦截 ...
- Vue2.x响应式原理
一.回顾Vue响应式用法 vue响应式,我们都很熟悉了.当我们修改vue中data对象中的属性时,页面中引用该属性的地方就会发生相应的改变.避免了我们再去操作dom,进行数据绑定. 二.Vue响应 ...
- [切图仔救赎]炒冷饭--在线手撸vue2响应式原理
--图片来源vue2.6正式版本(代号:超时空要塞)发布时,尤雨溪推送配图. 前言 其实这个冷饭我并不想炒,毕竟vue3马上都要出来.我还在这里炒冷饭,那明显就是搞事情. 起因: 作为切图仔搬砖汪,长 ...
- Vue2 响应式原理
我们经常用vue的双向绑定,改变data的某个属性值,vue就马上帮我们自动更新视图,下面我们看看原理. Object的响应式原理: 可以看到,其实核心就是把object的所有属性都加上getter. ...
- 由浅入深,带你用JavaScript实现响应式原理(Vue2、Vue3响应式原理)
由浅入深,带你用JavaScript实现响应式原理 前言 为什么前端框架Vue能够做到响应式?当依赖数据发生变化时,会对页面进行自动更新,其原理还是在于对响应式数据的获取和设置进行了监听,一旦监听到数 ...
随机推荐
- es分片shard的数量
适当的提升分片数量可以提升建立索引的速度: 一般情况下:一个索引库建立5-20个分片是最合适的: 注意:如果分片过少或者过多,都会降低检索的速度 分片数过多会导致: 1. 会导致打开比较多的文件2. ...
- HTTP入门(二):用Chrome开发者工具查看 HTTP 请求与响应
HTTP入门(二):用Chrome开发者工具查看 HTTP 请求与响应 本文简单总结HTTP的请求与响应. 本文主要目的是对学习内容进行总结以及方便日后查阅. 详细教程和原理可以参考HTTP文档(MD ...
- 箭头函数(Arrow Functions)
ES5语法: var getPrice = function() { return 4.55; }; console.log(getPrice()); ES6 中,箭头函数就是函数的一种简写形式,使用 ...
- 谷歌 AXURE RP EXTENSION拓展问题
我们打开某种文件页面是 会提示我们下载 AXURE RP EXTENSION 拓展. 其实我们可以直接用ie浏览器打开即可,不用下载
- ORACLE异机增量备份恢复
PROD异机增量备份恢复验证实施文档 准备工作:source 源库:PROD数据库备份策略:周日0级RMAN备份,周一至周六1级差异增量备份0 4 * * 0 /data/rmanlev0.sh &g ...
- 用流的方式来操作hdfs上的文件
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import ...
- jsonify返回中文乱码的问题
参考博客: 解决flask中文乱码的问题 返回内容如图: 实际填写的内容: 从网上找答案,结果很多都是说配置app.config,如下: app.config['JSON_AS_ASCII'] 但我试 ...
- 测开之路八十七:HTML之a标签的用法
初始化的HTML结构为,只需要在body里面加网页的标签和要显示的内容即可 <!DOCTYPE html><html lang="en"><head& ...
- Week 9 - 638.Shopping Offers - Medium
638.Shopping Offers - Medium In LeetCode Store, there are some kinds of items to sell. Each item has ...
- mysql数据库连接 application.properties
# 数据库链接信息mysql.driver=com.mysql.cj.jdbc.Drivermysql.url=jdbc:mysql://localhost:3306/xxxx?characterEn ...