实现简单的vue框架
实现简单的 Vue 框架
核心原理
Vue 的核心是数据劫持(响应式系统)和虚拟 DOM。通过 Object.defineProperty 或 Proxy 监听数据变化,结合虚拟 DOM 实现高效更新。
数据劫持实现
使用 Object.defineProperty 监听对象属性的读取和修改:
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log(`读取 ${key}: ${val}`);
return val;
},
set(newVal) {
if (newVal !== val) {
console.log(`设置 ${key}: ${newVal}`);
val = newVal;
// 触发更新
}
}
});
}
虚拟 DOM 简化实现
虚拟 DOM 是一个描述真实 DOM 的 JavaScript 对象:
function createElement(tag, props, children) {
return {
tag,
props,
children
};
}
渲染函数
将虚拟 DOM 转换为真实 DOM:
function render(vnode) {
if (typeof vnode === 'string') {
return document.createTextNode(vnode);
}
const el = document.createElement(vnode.tag);
for (const key in vnode.props) {
el.setAttribute(key, vnode.props[key]);
}
vnode.children.forEach(child => {
el.appendChild(render(child));
});
return el;
}
简易组件系统
定义组件构造函数和挂载方法:
function Vue(options) {
this.$options = options;
this._data = options.data();
this._el = document.querySelector(options.el);
this._compile();
}
Vue.prototype._compile = function() {
const html = this.$options.template;
const el = document.createElement('div');
el.innerHTML = html;
this._el.appendChild(el);
};
使用示例
const app = new Vue({
el: '#app',
data() {
return {
message: 'Hello Vue!'
};
},
template: `<div>{{ message }}</div>`
});
响应式系统扩展
结合数据劫持和依赖收集:
class Dep {
constructor() {
this.subscribers = [];
}
depend() {
if (target && !this.subscribers.includes(target)) {
this.subscribers.push(target);
}
}
notify() {
this.subscribers.forEach(sub => sub());
}
}
let target = null;
function watchEffect(cb) {
target = cb;
cb();
target = null;
}
模板编译
简单模板插值处理:
Vue.prototype._compile = function() {
const html = this.$options.template;
const el = document.createElement('div');
el.innerHTML = html.replace(/\{\{\s*(.*?)\s*\}\}/g, (_, exp) => {
return this._data[exp.trim()];
});
this._el.appendChild(el);
};
这个实现包含了 Vue 的核心概念:数据响应式、虚拟 DOM、组件系统和模板编译。实际 Vue 的实现更为复杂,包含更多优化和功能。







