Vue.js 是一个 MVVM(Model-View-ViewModel) 框架,它使用响应式的数据绑定来管理前端视图。Vue.js 的核心特性是数据响应式和组件化架构。
实现原理:
-
数据响应式
Vue.js 通过 Object.defineProperty()(ES5 特性)对属性进行劫持,当属性发生改变时,会触发响应式更新机制,即自动更新相关依赖的数据,从而自动更新视图。 -
模板解析
Vue.js 的模板是基于 HTML 的,当解析时,Vue.js 会解析指令(如 v-model、v-bind 等),并把它们转化成相应的数据绑定。 -
虚拟DOM
Vue.js 采用虚拟DOM,比较真实DOM的变化,当数据发生变化时,会计算新旧虚拟DOM树的差异,然后通过打补丁的方式来更新真实DOM。 -
组件化
Vue.js 将 UI 拆分成一个一个的组件,每个组件包含 HTML、CSS 和 JavaScript,使得代码更加模块化、易于维护。
下面使用 JavaScript+HTML 简易地实现一个 Vue 的响应式数据绑定:
HTML代码:
<div id="app">
<label for="name">姓名:</label>
<input type="text" id="name" v-model="name">
<br>
<label for="age">年龄:</label>
<input type="text" id="age" v-model="age">
<br>
<p>{{name}} 的年龄是 {{age}}</p>
</div>
JavaScript代码:
// 实现一个响应式对象
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log(`读取${key}: ${val}`);
return val;
},
set(newVal) {
console.log(`设置${key}: ${newVal}`);
val = newVal;
render(); // 数据变化后重新渲染
}
});
}
// 实现Vue
function Vue(options) {
this.data = options.data;
const keys = Object.keys(this.data);
keys.forEach(key => {
defineReactive(this.data, key, this.data[key]); // 劫持数据
});
}
// 渲染Vue视图
function render() {
let app = document.querySelector("#app");
app.innerHTML = `
<label for="name">姓名:</label>
<input type="text" id="name" v-model="name">
<br>
<label for="age">年龄:</label>
<input type="text" id="age" v-model="age">
<br>
<p>${vm.data.name} 的年龄是 ${vm.data.age}</p>
`;
}
// 测试
const vm = new Vue({
data: {
name: "Tom",
age: 18
}
});
render(); // 第一次渲染视图
以上代码就实现了一个简单的 Vue 响应式数据绑定,数据变化后自动更新视图。我们使用 v-model 在视图中展示数据并实现双向数据绑定,渲染函数 render() 会根据数据变化来更新视图。