系列文章目录
目录
前言
vue原理相关
一、MVVM
MVVM,是Model-View-ViewModel三部分组成。
二、vue响应式
核心API-Object.defineProperty
Object.defineProperty缺点:
- 深度监听,需要递归到底,一次性计算量大
- 无法监听新增属性、删除属性(Vue.set Vue.delete)
- 无法原生监听数组,需要特殊处理
如何监听数组
function observer(target){
if(typeof target !== 'object' || target === null){
// 不是对象或数组
return target;
}
if(Array.isArray(target)){
target.__proto__ = arrProto;
}
// 重新定义各个属性(for in 可以遍历数组和对象)
for(let key in target){
defineReactive(target, key, target[key])
}
}
// 重新定义数组原型
const oldArrayProperty = Array.prototype;
// 创建新对象,原型指向 oldArrayProperty,再扩展新的方法不会影响原型
const arrProto = Object.create(oldArrayProperty);
['push','pop','shift','unshift','splice'].forEach(methodName => {
arrProto[methodName] = function() {
undateView(); // 触发视图更新
oldArrayProperty[methodName].call(this, ...arguments);
}
})
// 重新定义属性,监听
function defineReactive(target, key, value){
// 深度监听
observer(value)
// 核心API
Object.defineProperty(target, key, {}
get() {
return value;
},
set(newValue) {
if(newValue !== value){
// 深度监听
observer(newValue);
// 设置新值
// 注意,value 一直在闭包中,此处设置完之后,再get时也是可以拿到的
value = newValue
// 触发更新视图
updateView()
}
}
)
}
三、虚拟DOM(Virtual DOM)和diff
vdom(数据驱动视图,控制DOM操作)
- 用JS模拟DOM结构(vnode)
- 新旧vnode对比,得出最小的更新范围,最后更新DOM
- 数据驱动视图的模式下,有效控制DOM操作
diff算法
- 只比较同一层级,不跨级比较
- tag不相同,则直接删掉重建,不再深度比较
- tag 和 key,两者都相同,则认为是相同节点,不再深度比较
- patchVnode
- addVnodes removeVnodes
- updateChildren(key的重要性)
四、初次渲染过程
- 解析模板为 render 函数(或在开发环境已完成,vue-loader)
- 触发响应式,监听data属性 getter setter
- 执行 render 函数,生成 vnode,patch(elem,vnode)
五、更新过程
- 修改data,触发setter(此前在getter中已被监听)
- 重新执行render函数,生成newVnode
- patch(vnode,newVnode)
六、异步渲染
- $nextTick
- 汇总data的修改,一次性更新视图
- 减少DOM操作次数,提高性能
七、前端路由原理
hash特点
- hash变化会触发网页跳转,即浏览器的前进、后退
- hash变化不会刷新页面,SPA必需的特点
- hash永远不会提交到server端
- window.onhashchange监听
H5 history(需要后端支持)
- 用url规范的路由,但跳转时不刷新页面
- history.pushState(打开新的路由,浏览器不会刷新)
- window.onpopstate(监听浏览器前进、后退)
vue原理的三大块:响应式、vdom和diff、模板编译
总结
vue原理