1、util.js
// 正则,?:匹配不捕获 不捕获当前的分组
// + 至少一个
// ?尽可能少匹配
// 源码里的模板编译 也是基于正则的
const defaultRE = /\{\{((?:.|\r?\n))+?\}\}/g;
export const util = {
getValue(vm,expr){ //school.name
let keys=expr.split('.');
return keys.reduce((memo,current)=>{ //reduce具备迭代的功能
memo=memo[current]; //memo =vm.school
return memo;
},vm)
},
compilerText(node, vm) {
//编译文本 替换{{}}
node.textContent = node.textContent.replace(
defaultRE,
function (...args) {
return util.getValue(vm,args[1]);
}
);
},
};
export function compiler(node, vm) {
//node就是文档碎片
let childNodes = node.childNodes; // 只有一层 只有儿子 没有孙子
// 将类数组转化成数组
[...childNodes].forEach((child) => {
//一种是元素,一种是文本
if (child.nodeType == 1) {
//1 元素 3表示文本
compiler(child,vm); //编译当前元素的孩子节点
} else if (child.nodeType == 3) {
util.compilerText(child, vm);
}
});
}
2、index.js
import { initState } from "./observe";
import Watcher from "./observe/watcher";
import { compiler,util } from "./util";
function Vue(options) {
//vue中原始用户传入的数据
this._init(options); // 初始化vue并且将用户选项传入
}
Vue.prototype._init = function (options) {
//vue中初始化, this.$options 表示的是vue中参数
let vm = this;
vm.$options = options;
// MVVM原理 需要数据重新初始化
// 拦截数组的方法 和对象的属性
initState(vm); // data computed watch
// 初始化工作
if (vm.$options.el) {
vm.$mount();
}
};
function query(el) {
if (typeof el === "string") {
return document.querySelector(el);
}
return el;
}
Vue.prototype._update = function () {
// 用户传入的数据 去更新视图
let vm = this;
let el = vm.$el;
// 要循环这个元素 将里面的内容 换成我们的数据
// 需要匹配{{}} 的方式来进行替换
let node = document.createDocumentFragment();
let firstChild;
while ((firstChild = el.firstChild)) {
//每次拿到第一个元素 就将这个元素放入到文档碎片中。
node.appendChild(firstChild); //appendChild 是具有移动功能的。
}
compiler(node, vm);
el.appendChild(node);
// 需要匹配{{}} 的方式来进行替换
// 依赖收集 属性变化了 需要重新渲染 watcher和deep
};
// 渲染页面 将组建进行挂载
Vue.prototype.$mount = function () {
let vm = this;
let el = vm.$options.el; //获取元素
el = vm.$el = query(el); //获取当前挂载的节点 vm.$el就是我要挂载的一个元素
// 渲染是通过watcher来渲染的。
// 渲染watcher 用于渲染的watcher
// Vue 2.0 组建级别的更新 new Vue 产生的一个组件
let updateComponent = () => {
//更新组件,渲染组件
console.log("执行");
vm._update(); //更新组件
};
new Watcher(vm, updateComponent); //渲染watcher,默认会调用updateComponent 这个方法
};
export default Vue;
3、reduce具有迭代的功能
[1,2,3].reduce((memo,current)=>{
memo+=current;
return memo;
},0);
// 累加器
4、正则 (匹配{{}})
const defaultRE = /\{\{((?:.|\r?\n))+?\}\}/g;
// 正则,?:匹配不捕获 不捕获当前的分组
// + 至少一个
// ?尽可能少匹配
// 源码里的模板编译 也是基于正则的
'{{}}'.match(/\{\{((?:.|\r?\n))+?\}\}/g);