原理篇
本章是以上一章为基础上来深入理解vuejs的设计思想,
vue中比较出彩的是虚拟DOM,响应式数据数据操作(数据双向绑定)以及丰富的生态库(vue-router vuex iview….)。
1.vue中的响应式数据
在数据双向绑定这个理念出来之前,前端中都是使用jQuery或原生js操作DOM来实现数据变化。这不仅实现过程麻烦,也对页面的性能有很大的影响。vue框架中的核心理念就是响应式,因此了解响应式的原理可以帮助我们解决vue中遇到的大部分问题,也能加深我们对vue的了解。
- 原理
vue响应式原理是靠Object.defineProperty实现的
这个方法会在对象上添加新的属性,或者修改对象上的属性并返回这个对象。详细可以查看MDN
Object.defineProperty(obj,prop,descriptor)
obj要在其上定义属性的对象。
prop要定义或修改的属性的名称。
descriptor将被定义或修改的属性描述符 - 实现
在New vue()创建后,数据初始化开始,使用Object.defineProperty方法实现响应式
第一步先要遍历vue data中所有的变量
function observer (value) {
if (!value || (typeof value !== 'object')) {
return;
}
Object.keys(value).forEach((key) => {
defineReactive(value, key, value[key]);
});
}
第二步将每个变量实现响应式
Object.defineProperty(obj, key, {
//key data中定义的数据
enumerable: true,
configurable: true,
//数据的读取时调用
get: function reactiveGetter () {
return val;
},
//数据的改变时调用
set: function reactiveSetter (newVal) {
if (newVal === val) return;
cb(newVal);
}
});
}
感兴趣的同学可以自己试着实现一个响应数据
依赖收集追踪
在vue中数据的变化会触发视图更新,视图变化会同时改变数据。这种情况看似是响应式的全部,但有种情况,当data中的某个数据不用显示在视图上并且他会不断的变化。这时如果视图不断的更新显然不合理,我们需要能够判断某个数据的变化是否有必要更新视图。
2.vue中实现Virtual DOM过程
Vue中 的虚拟DOM操作是其核心概念之一,其实质就是将vue render函数转化成Vnode节点。然后用JavaScript中对象的形式表示,以JavaScript中对象的属性来描述vnode节点。
- 获取Vue 组件(假设如下组件)
<template>
<p class="demo" v-if="isShow">
This is a span.
</p>
</template>
- 解析vue组件(转换后)
{
tag: 'p',
data: {
/* 指令集合数组 */
directives: [
{
/* v-if指令 */
rawName: 'v-if',
expression: 'isShow',
name: 'show',
value: true
}
],
/* 静态class */
staticClass: 'demo'
},
text: undefined,
children: [
/* 子节点是一个文本VNode节点 */
{
tag: undefined,
data: undefined,
text: 'This is a span.',
children: undefined
}
]
}
内部的具体实现过程可参见《实现 Virtual DOM 下的一个 VNode 节点》。