数据双向绑定通过监听数据变化、收集依赖、派发更新和监听DOM实现视图与模型同步,可用Object.defineProperty或Proxy手动实现响应式系统。

数据双向绑定是现代前端开发中的核心机制之一,它让视图与数据模型自动同步。虽然现在有 Vue、React 等成熟框架提供支持,但理解其原理并手动实现一个轻量级的 JS 插件,有助于深入掌握响应式编程的本质。
数据双向绑定指的是:当数据模型发生变化时,视图自动更新;当用户操作视图(如输入框输入内容)时,数据模型也同步更新。
实现这一机制的关键点包括:
下面是一个基于 ES5 的简单数据绑定插件示例,适用于不支持 Proxy 的旧环境。
立即学习“Java免费学习笔记(深入)”;
function MVVM(options) {
this.data = options.data;
this.el = document.querySelector(options.el);
this.methods = options.methods || {};
this.observe(this.data);
this.compile(this.el);
}
MVVM.prototype.observe = function(data) {
if (!data || typeof data !== 'object') return;
Object.keys(data).forEach(key => {
this.defineReactive(data, key, data[key]);
});
};
MVVM.prototype.defineReactive = function(obj, key, val) {
const dep = [];
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get() {
if (window.target) {
dep.push(window.target);
}
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
dep.forEach(fn => fn());
}
});
};
MVVM.prototype.compile = function(el) {
const childNodes = el.childNodes;
childNodes.forEach(node => {
const reg = /\{\{(.*)\}\}/;
if (node.nodeType === 3 && reg.test(node.textContent)) {
const prop = RegExp.$1.trim();
window.target = () => {
node.textContent = reg.test(node.textContent)
? node.textContent.replace(reg, this.data[prop])
: '';
};
window.target(); // 初始化
window.target = null;
}
if (node.nodeType === 1) {
const attrs = node.attributes;
for (let attr of attrs) {
if (attr.name === 'v-model') {
const propName = attr.value;
node.value = this.data[propName];
node.addEventListener('input', e => {
this.data[propName] = e.target.value;
});
// 建立反向绑定
window.target = () => { node.value = this.data[propName]; };
window.target();
window.target = null;
}
}
}
if (node.childNodes.length) this.compile(node);
});
};
使用方式:
const vm = new MVVM({
el: '#app',
data: {
message: 'Hello World'
}
});
HTML 示例:
<div id="app">
<input v-model="message" />
<p>{{ message }}</p>
</div>
ES6 的 Proxy 能拦截整个对象的操作,比 defineProperty 更强大,可监听新增/删除属性。
class Reactive {
constructor(data, updateCallback) {
this.update = updateCallback;
this.proxy = new Proxy(data, {
get: (target, key) => {
return typeof target[key] === 'object' && target[key] !== null
? new Reactive(target[key], this.update).proxy
: target[key];
},
set: (target, key, value) => {
target[key] = value;
this.update(); // 视图更新
return true;
}
});
}
}
结合模板编译使用:
function bindData(el, data) {
const render = () => {
el.innerHTML = el.innerHTML.replace(/\{\{(.*)\}\}/g, (match, key) => {
return key.split('.').reduce((o, k) => o[k], data);
});
};
const reactive = new Reactive(data, render);
render(); // 初始渲染
return reactive.proxy;
}
一个实用的插件可以逐步增强以下能力:
以上就是JS插件如何实现数据绑定_JavaScript数据双向绑定插件开发方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号