手动实现合计vue
手动实现 Vue 的核心功能
Vue 的核心功能包括数据响应式、模板编译、虚拟 DOM 和组件系统。以下是手动实现这些功能的简化版本。
数据响应式
通过 Object.defineProperty 或 Proxy 实现数据劫持,监听数据变化并触发更新。
function defineReactive(obj, key, val) {
const dep = new Dep();
Object.defineProperty(obj, key, {
get() {
if (Dep.target) {
dep.addSub(Dep.target);
}
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify();
},
});
}
class Dep {
constructor() {
this.subs = [];
}
addSub(sub) {
this.subs.push(sub);
}
notify() {
this.subs.forEach(sub => sub.update());
}
}
模板编译
将模板字符串解析为 AST(抽象语法树),并生成渲染函数。
function compile(template) {
const ast = parse(template);
const code = generate(ast);
return new Function(`with(this) { return ${code} }`);
}
function parse(template) {
// 简化版解析逻辑
return {
type: 'element',
tag: 'div',
children: [{ type: 'text', content: 'Hello Vue' }],
};
}
function generate(ast) {
// 简化版代码生成
return `_c('div', [_v('Hello Vue')])`;
}
虚拟 DOM
创建虚拟节点并实现简单的 diff 算法。
function createElement(tag, data, children) {
return { tag, data, children };
}
function createTextNode(text) {
return { text };
}
function patch(oldVnode, vnode) {
if (!oldVnode) {
// 首次渲染
return createElm(vnode);
} else {
// 更新
const el = oldVnode.el;
if (vnode.tag === oldVnode.tag) {
// 更新属性
updateAttrs(el, vnode.data, oldVnode.data);
// 更新子节点
patchChildren(el, vnode.children, oldVnode.children);
}
return el;
}
}
function createElm(vnode) {
if (vnode.text) {
return document.createTextNode(vnode.text);
}
const el = document.createElement(vnode.tag);
updateAttrs(el, vnode.data);
vnode.children.forEach(child => {
el.appendChild(createElm(child));
});
vnode.el = el;
return el;
}
组件系统
实现组件注册和渲染。
class Vue {
constructor(options) {
this.$options = options;
this._data = options.data();
this._init();
}
_init() {
// 数据响应式
observe(this._data);
// 编译模板
this.$mount();
}
$mount() {
const updateComponent = () => {
const vnode = this.$options.render.call(this);
patch(this._vnode, vnode);
this._vnode = vnode;
};
new Watcher(this, updateComponent);
}
}
class Watcher {
constructor(vm, fn) {
this.vm = vm;
this.fn = fn;
Dep.target = this;
this.fn();
Dep.target = null;
}
update() {
this.fn();
}
}
使用示例
const app = new Vue({
data() {
return { message: 'Hello Vue' };
},
render() {
return createElement('div', null, [
createTextNode(this._data.message),
]);
},
});
以上代码展示了 Vue 核心功能的简化实现,实际 Vue 源码更加复杂和完善。







