vue响应式原理整理
vue是数据响应性,这是很酷的一个地方。本文只为理清逻辑。详细请看官方文档 https://cn.vuejs.org/v2/guide/reactivity.html
vue的data在处理数据时候,会遍历data内对象的所有属性,并使用Object.defineProperty将属性转为getter/setter。 这里的getter/setter对用户是不可见的,但是方便vue对数据进行内部跟踪,来维护数据。
用Object.defineProperty这是一个ES5无法支持特性,所有vue不支持IE8以及更低级的浏览器
流程入上图,每个data里的数据都相应的有一个watcher实例,用来监听数据变化,当数据发布变化时候,watcher去触发相应的组件渲染函数并讲具体数据渲染到DOM上面
原始数据数据处理增加监听实例调用渲染函数组件变化
由于jacascript的限制,vue不能直接检测到数组和对象的变化。
数组:
1 // 数组
2
3 const app = new Vue({
4 data: {
5 arr: ['a', 'b', 'c']
6 }
7 })
8
9
10
11 app.arr[0] = 'd' // 非响应式
12 app.arr.length = 4 // 非响应式
Vue为了解决改变数组内元素的问题,采取了两种方法
第一种: Vue.set,vue的全局方法,可以用来改变数据,或者是直接使用实例的 app.$set(),它是Vue的全局方法的一个别名。
如:
1 // 全局
2 Vue.set(app.arr, indexOfItem, newValue)
3
4 // 实例
5 app.$set(app.arr, indexOfitem, newValue)
第二种:使用数组的splice方法
1 app.arr.splice(indexofItem, 1, newValue)
对于改变数组长度,也可以采取splice方法
1 app.arr.splice(newLength)
对象:
vue无法检测到property的添加和删除,由于data如上述所讲,需要进行初始化getter/setter来进行管理,而类似于直接添加这种方法是无法响应的
如:
1 const app = new Vue({
2 data: {
3 a: 1
4 }
5 })
6
7
8 app.a // 是响应式,因为数据已经初始化
9
10 app.b = 2 // 不是响应式,无法监听到
对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。
但是,可以使用Vue.set这个全局方法向嵌套对象添加响应式属性
如:
1 Vue.set(vm.someObject, 'b', 2)
同上,也可以直接使用实例的$set方法
由于 Vue 不允许动态添加根级响应式属性,所以你必须在初始化实例前声明所有根级响应式属性,哪怕只是一个空值
重点:vue的更新DOM是异步的,当Vue监听到数据变化时候,会创建一个队列,并缓冲在同一事件循环中数据变更。如果一个watcher被多次触发,也不会造成重复推入,Vue会去除重复数据来避免不必要的计算。在下一个事件循环’tick‘。 Vue 在内部对异步队列尝试使用原生的 Promise.then
、MutationObserver
和 setImmediate
,如果执行环境不支持,则会采用 setTimeout(fn, 0)
代替。
这往往是需要注意的,由于更新DOM是异步的,而如果你需要在数据更新后来操作DOM,这往往会产生奇怪的错误。
踩坑点:
讲一个例子。比如需要在一个dom上面挂载或者监听一个内容时候,往往会出错。比如使用v-if来进行dom渲染,由于dom还未渲染,会直接导致挂载失败。这也是Vue不建议直接操作dom的原因。
或者是通过data里的数据来重新刷新一些插件的值,由于数据是异步刷新的,可能会导致传输到插件的值还是原值,导致插件刷新失败。
这里Vue提供一个Vue.nextTick(callback)的方法,这样可以在dom都渲染完毕后再执行我们相关的业务代码。
最新文章
- mvc 3 Mvc 4 使用Forms 登录验证随笔一
- CMS为什么采用“标记-清除”算法
- ArcServer 10.0 “No Content”、“Server Host Cannot be null” 错误
- OpenXML_导入Excel到数据库(转)
- PAT乙级 1008. 数组元素循环右移问题 (20)
- foundation框架之反射机制
- Html中版权符号的字体选择问题(如何让版权符号更美观)
- MySQL多表查询之外键、表连接、子查询、索引
- 轻量级IOC框架:Ninject
- Unreal Engine 4(虚幻UE4)GameplayAbilities 插件入门教程(七)Ability的信息传递等
- Angular2入坑指南
- Web前端方向课程要点:CSS3渐变制作过程
- Centos7安装Nginx+PHP+MySQL
- PLSql的使用
- BarTender中如何为称重设备设置秤显示?
- 【Spring】14、SpringMVC拦截器的配置
- 修改idea自动生成在C盘的文件路径,以免电脑越用越卡
- Asp.Net T4模板生成三层架构
- 【转载】 AI会议的总结(by南大周志华)
- 探索未知种族之osg类生物---器官初始化一