mvvm.js(中枢办公室)
* ifredom同学,来到公司,刚刚刷完新闻,准备开始愉快的工作。
* 突然收到消息,下午领导要来视察了!
* 这下可好,得先拿出一个肉眼可见的成果出来展示。
* 怎么办呢?先把最终的样子做出来,至于里面是什么状态嘛,大家都懂。
* 还好,有现成的Vue可以模仿,那就先模仿调用写写看。
index.html
先观摩观摩Vue官方给出的极简示例是什么样。
一部分html内容, 一部分JS内容,一部分最终呈现UI。其中核心的JS内容,通过类Vue
创建了一个实例 app
,其中传了一个对象形式的参数,参数内含有两项 el
和data
.
* ifredom 想了想,直接创建 index.html ,模仿Vue参数调用的形式.
* 引入一个空文件 mvvm.js 模拟vue.js.
* 当然也要有一个获取参数的操作,打印一下。
* 也要有一个改变参数的操作,使用延时模拟一下。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>mvvm-demo</title>
</head>
<body>
<div id="app">
<div class="name"></div>
</div>
<script src="mvvm.js"></script>
<script>
var vm = new Mvvm({
el: "#app",
data: {
name: "ifredom"
}
})
console.log(vm); // Mvvm(...)
// 获取参数,并打印
console.log(vm.name); // undefined
setTimeout(() => {
// 设置参数
vm.name = "newValue";
console.log(vm); // Mvvm(...)
console.log(vm.name); // newValue
}, 2000);
</script>
</body>
</html>
* 经过观察,Vue是一个类,el参数,作用是存储dom节点,获取方式类似jquery。
* data参数不知道有啥用,先保存在this._data上。
* (此处取名为_data也是跟vue保持一致)
mvvm.js
class Mvvm {
constructor(options) {
this.el = document.querySelector(options.el);
this._data = options.data;
}
}
* mvvm.js(中枢办公室)的架子已经搭建起来了, index调用mvvm类.
* var app = new Vue(...)
* 这里有个问题,Vue所有在data中的参数都是可以直接通过新创建的实例app.message拿到......
* 而我写的vm.name打印结果是 undefined,说明没有获取到data传入的参数
* 先把这一步模仿出来,使用跟vue一样的方式:
// mvvm.js
class Mvvm {
constructor(options) {
this.el = document.querySelector(options.el);
this._data = options.data; //
this.proxyData(options.data);
}
// 参数代理, 实现 vm.xxx -> vm._data.xxx
proxyData(data) {
Object.keys(data).forEach((key) => {
Object.defineProperty(this, key, {
get() {
return this._data[key];
},
set(newValue) {
this._data[key] = newValue;
},
enumerable: true,
configurable: true,
});
});
}
}
写好了代理参数后,再测试一下参数的读写情况
// index.html
<script>
var vm = new Mvvm({
el: "#app",
data: {
name: "ifredom"
}
})
console.log(vm); // Mvvm(...)
console.log(vm.name); // ifredom !!!不再是undefined
setTimeout(() => {
vm.name = "Tom";
console.log(vm); // Mvvm(...)
console.log(vm._data.name);// Tom
console.log(vm.name); // Tom 代理成功
}, 2000);
</script>
ui更新
* 办公室已经搭建好了,(获取)收集信息,(设置)发送信息也已经没有问题,距离给boss展示的PPT产品,只差让信息 (data) 的变化在UI上表现出来。
* 这一步就需要朝阳市民(compile)去执行,首先收集UI信息,然后在收到信息变化后,能够更新UI.
* 不过时间紧迫啊,PPT产品,能变化UI即可。
* 所以,一旦set值,那么我就更新UI.
很简单就一句代码。
// 参数代理, 实现 vm.xxx -> vm._data.xxx
proxyData(data) {
Object.keys(data).forEach((key) => {
Object.defineProperty(this, key, {
get() {
return this._data[key];
},
set(newValue) {
this.el.innerHTML = this._data[key]; // 更改模板数据的值
this._data[key] = newValue;
},
enumerable: true,
configurable: true,
});
});
}
* 呵呵,应付BOSS足够了.
* 天网监控系统(MVVM)不就是这样么,数据变化,UI更新,这不就成了么?
* 不过我们显然不能止步于此,给boss优化用户体验,提升产品竞争力,拿下年度最强PPT...
* 添加个输入框可以输入任意数据,而不是将数据在代码里写死。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>mvvm-demo</title>
</head>
<body>
<div id="app"></div>
<input type="text" id="input">
<script src="mvvm.js"></script>
<script>
var vm = new Mvvm({
el: "#app",
data: {
name: "ifredom"
}
})
setTimeout(() => {
vm.name = "Tom";
}, 2000);
var input = document.querySelector("#input");
input.addEventListener("input",function(e){
vm.name = e.target.value;
})
</script>
</body>
</html>
PPT展示效果
------ 如果文章对你有用,感谢>>>点赞 | 收藏 <<<