Skip to content

Vue 学习(二)

Published: at 11:00 AMSuggest Changes

时隔一年,学习 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);
}

后记

这次看源码只知道了流程和思路,但是还没有道能手写的地步。


Previous Post
Nginx 前端配置与二级路由详解
Next Post
Excel 文件大小为何有时小于 TXT 文件