由于读源码实在是枯燥又无趣,所以我放弃了读源码,只是想搞懂一些原理性知识点,所以有以下笔记,(但这并不是原理大全,毕竟20%的功能可以满足80%的需求)
(模板到render函数,再到vnode,再到渲染和更新)
vue响应式
核心API-Object.defineProperty(vue-MVVM数据驱动视图)
Object.defineProperty基本语法
cosole.log(data.name) // get zhangsan
data.name = 'lisi' // set
监听简单对象
// 触发视图更新
function updateView() {
console.log('视图更新了');
}
// 重新定义属性,监听起来
function defineReactive(target,key,value){
Object.defineProperty(target,key,{
get(){
return value;
},
set(newVal){
if(newVal !== value){
// 设置新值
newVal = value;
// 更新视图
updateView();
}
}
})
}
// 监听对象属性
function observer(target){
// 不是对象和数组不监听
if(typeof target !== 'object' || target === null){
return target;
}
// 重新定义各个属性
for(let key in target){
defineReactive(target,key,target[key])
}
}
// 数据
let data = {
name:'zhangsan',
age:20
}
observer(data)
// 测试
data.name = 'lisi';
data.age = 20;
监听复杂对象
// 出发视图更新
function updateView(){
console.log('视图更新了');
}
// 重新定义属性,监听起来 递归
function defineReactive(target,key,value){
// 深度监听
observer(value);
Object.defineProperty(target,key,{
get(){
return value;
},
set(newVal){
if(newVal !== value){
// 深度监听
observer(value);
// 设置新值
newVal = value;
// 视图更新
updateView();
}
}
})
}
// 监听对象属性
function observer(target){
// 如果不是对象和数组不进行监听
if(typeof target !== 'object' || target === null){
return target
}
// 重新定义各个属性
for(let key in target){
defineReactive(target,key,target[key]);
}
}
let data = {
name:'zhangsan',
age:20,
// 需要深度监听
info:{
address:'北京'
}
}
observer(data);
几个缺点:
深度监听,需要递归到底,一次性计算量大
无法监听新增属性/删除属性
无法原生监听数组,需要特殊处理