【vue 原理相关】

组件化和 MVVM

组件化:

很早以前就有 组件化 的概念,比如 asp, jsp, php。node也有类似的组件化,但是传统组件化,只是做分模块做静态渲染,更新数据时需要操作 DOM 节点,也就是 jQuery 比较流行时,vue 和 react 在 此基础上增加了创新,即为 数据驱动视图,通过 MVVM 原理实现。

数据驱动视图:

V-view
VM-viewModel
M-model

view:代表 template 模板中的内容
model: 代表 vue中的data,react中的 state。
viewModel: 泛指view和model的连接层,通过监听事件和指令修改model中的数据

响应式原理

通过核心api Object.defineproperty 监听属性变化
通过 Vue.set 和 Vue.delete 监听对象属性的增加和删除
通过 重写数组原型 监听数组

  1. updateView - 更新视图
  2. 重写数组原型
const oldArrayProperty = Array.prototype;
const arrProto = Object.create(oldArrayProperty);
[...数组原型的基础方法].forEach(methodName => {
	arrProto[methodName] = function() {
		updateView() // 更新视图
		oldArrayProperty[methodName].call(this, ...arguments)
	}
})
  1. 核心API -> 深度监听 -> 核心API 监听
function defineReactive(target, key value){
	observe(value) // 多层对象深度监听,一次性递归到底
	Object.defineProperty(target, key {
		get(){
			return value
		},
		set(newValue){
			if(newValue !== value){
				observe(newValue) // 对象类型监听,如果从 直接变量 修改为 对象则需要深度监听
				value = newValue
				updateView() // 更新视图
			}
		}
	})
}
  1. 递归深度监听
function observe(target){
	if(typeof target !== 'object' || target === null) return target;
	if(Aray.isArray{target}){
		target.__proto__ = arrProto
	}
	for(let key in target){
		defineReactive(target, key , target[key])
	}
}
  1. model
const data = {
	name: '张三'
}
// 开启响应式监听
observe(data) 

vdom 和 diff 算法

vdom

总所周知,DOM 操作比较费时,一般都是通过jQuery操作DOM,但 vue 和 react 都是数据驱动视图,有效的通过 vdom 优化DOM 操作;
所以vdom可以说是 用 JS 模拟 dom 结构,计算出最小的变更,再去操作 DOM

diff 算法

首先 vue 把树 diff 的时间复杂度O(n^3) , 优化到 O(n);
根据统一层级对比,不做跨级比较;
elem 不相同,则删掉重建,不再做深度比较;
elem 和 key 两者都相同,则认为是相同节点,通过 patchVnode 做比较
patchVnode 通过对比 oldVnnode 和 newVnode做比较,对应判断是应该做 add 还是 remove操作
最终节点和key都相同并且都有chillren 的节点 通过 update Children 做对比,最终返回最新的vnode渲染到 DOM 节点中。

模板编译

了解模板编译之前需要先了解一下开发中不常用到的 with 语法;在此不赘述。
通过 vue-template-complier 将模板解析为 render 函数,render 通过 with 语法返回一个 vnode 节点

组件渲染和更新过程

渲染-解析 template 模板为render 函数,触发监听 model 的 getter 和 setter;
执行render 函数,生成 vnode 节点。通过 patch 函数,挂在到 对应的包裹容器中
更行-当 model 中值被改变的时候,会触发 getter 中 已经观察者模式中的数据,触发 setter。
重新执行 render 函数,生成 newVnode ,通过 patch 函数中的oldVnode,newVnode 对比(diff),得出最小差值的新节点后更新视图

touch
getter
re-render
setter
render
Component-render-function
data-getter-setter
Watcher
vdom

异步渲染

首先 $nextTick 是在新增或者删除完节点之后立即可以获得元素的真实内容和节点长度时使用。
多次 setData 的时候会汇总 data 设置,一次性更新视图,减少 DOM 操作次数,提高性能。

随手记录,望指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值