时隔一年,学习 Vue 源码
Vue 代码
/**
* Define a property.
*/
export function def(obj: Object, key: string, val: any, enumerable?: boolean) {
Object.defineProperty(obj, key, {
value: val,
enumerable: !!enumerable,
writable: true,
configurable: true,
});
}
练习
let car = {};
let val = 3000;
Object.defineProperty(car, 'price', {
enumerable: true,
configurable: true,
get() {
console.log('price 属性被读取了');
return val;
},
set(newVal) {
console.log('price 属性被修改了');
val = newVal;
},
});
感觉自己白学了的一段代码
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
console.log(new Food('cheese', 5).name);
// expected output: "cheese"
原来 call 除了改变 this 指向,还可以继承
const childNodes = el.childNodes;
Array.from(childNodes).forEach((node) => {
if (this.isElement(node)) {
// 如果是元素节点
/**
* 处理指令 j-xxx @xxx ...
*/
} else if (this.isInterpolation(node)) {
// 如果是插值表达式 {{ xx }}
this.compileText(node);
}
// 如果有子元素 递归
if (node.childNodes && node.childNodes.length > 0) {
this.compile(node);
}
});
// 这个代码不知道是干啥的,看上去很强 比如 RegExp.$1.trim() https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/n
compileText(node) {
const exp = RegExp.$1.trim(); // 获取插值表达式的内容
this.update(node, this.$vm, exp, 'text'); // 统一入口
}
// 这个也很有意思,特意去了 MDN https://developer.mozilla.org/zh-CN/docs/Web/API/Node/nodeType
isElement(node) {
return node.nodeType === 1;
}
// 这个就是哪个我想问题的 vue 怎么知道 {{}} 是插值表达式
isInterpolation(node) {
return node.nodeType === 3 && /\{\{(.*)\}\}/.test(node.textContent);
}
后记
这次看源码只知道了流程和思路,但是还没有道能手写的地步。