MVVM案例
- 说在前面的
- [从 GG BOND 的输入框看 MVVM:用原生 JS 写一个最小 Vue](#从 GG BOND 的输入框看 MVVM:用原生 JS 写一个最小 Vue)
说在前面的
- 波煮这篇文章是AI生成的,哈哈哈AI还是太强大了,我给了代码让它写一篇博客,他就可以写的这么有模有样!
从 GG BOND 的输入框看 MVVM:用原生 JS 写一个最小 Vue
不需要 Webpack、不需要脚手架,30 行代码就能体验"数据驱动视图"的魔法。
一、什么是 MVVM?
MVVM 把前端代码拆成 3 个字母:
- M (Model) :纯数据,不含 DOM
- V (View) :纯页面,不含业务逻辑
- VM (View-Model):调度中心,负责"数据 → 视图"和"视图 → 数据"的双向同步
结果:修改数据即可刷新页面,操作页面也能自动更新数据------像 Vue 一样丝滑,但用的是原生 API。
二、Model 层:只有数据,没有 DOM
js
const data = {
inputValue: ''
}
- 不读取
document,不操作innerHTML - 它只是一段普通 JavaScript 对象,代表"当前状态"
三、View 层:只有 HTML,没有逻辑
html
<input type="text" id="input">
<div id="content"></div>
- 纯粹的结构和样式占位符
- 所有变化由 VM 驱动,View 本身"无感知"
四、View-Model 层:双向同步的"魔法胶水"
VM 分为两条单向流,拼成双向绑定:
1. 视图 → 数据(事件监听)
js
const input = document.getElementById('input');
input.addEventListener('input', (e) => {
proxy.inputValue = input.value; // 修改 Model
});
- 用户敲键盘 → 触发
input事件 → 更新 Model - View 不直接操作 Model,而是通过 VM 转发
2. 数据 → 视图(Proxy 拦截)
js
const proxy = new Proxy(data, {
set: (target, key, value) => {
target[key] = value; // 先更新数据
if (key === 'inputValue') {
document.getElementById('content').innerHTML = value; // 再驱动视图
}
return true;
}
});
- 只要
proxy.inputValue = xxx,VM 自动把值塞进<div> - 无需手动操作 DOM,实现"数据驱动视图"
五、运行效果
- 在输入框敲字 → 下方
<div>实时同步 - 控制台打印
set调用 → 验证拦截生效 - 整个流程无刷新、无模板引擎、无框架,纯原生实现 MVVM
六、总结一句话
Model 只管数据,View 只管展示,View-Model 用 Proxy + 事件把它们粘成双向绑定------这就是最小但完整的 MVVM 循环,也是 Vue、React 状态管理的底层思想雏形。
完整代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MVVM案例 </title>
</head>
<body>
<h1>GG BOND</h1>
<!-- View层 -->
<input type="text" id="input" />
<div id="content"></div>
</body>
<script>
window.onload = () => {
// Model层
const data = {
inputValue: ''
}
// View-Model层
// 视图 -> 数据
const input = document.getElementById('input');
input.addEventListener('input',(e)=>{
proxy.inputValue = input.value
})
// 数据 -> 视图
const proxy = new Proxy(data,{
set: (target,key,value) => {
console.log(target,key,value)
target[key] = value;
if(key == "inputValue"){
const content = document.getElementById('content');
content.innerHTML = value;
}
}
})
}
</script>
</html>