脚本宝典收集整理的这篇文章主要介绍了创建MVVM框架,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" v-model="number">
<button v-click="increment">add</button>
<h3 v-bind="number"></h3>
</div>
</body>
<script>
class MyVue {
constructor(options) {
this.$options = options;
this.$el = document.querySelector(options.el);
this.$data = options.data;
this.$methods = options.methods;
this._binding = {}; // 依赖收集
this._observe(this.$data); // 观察data数据添加到Watcher中
this._compile(this.$el); // 编译为抽象语法树AST 这里要简单得多
}
_observe(obj) {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
this._binding[key] = {
_directives: []
};
console.log("this._binding[key]", this._binding[key]);
let value = obj[key];
if (typeof value === "object") {
this._observe(value);
}
let binding = this._binding[key];
Object.defineProperty(this.$data, key, {
enumerable: true,
configurable: true,
get() {
console.log(`${key}获取${value}`);
return value;
},
set(newVal) {
console.log(`${key}设置${newVal}`);
if (value !== newVal) {
value = newVal;
binding._directives.forEach(item => item.update());
}
}
});
}
}
}
_compile(root) {
// root为根节点,传入的el
let _this = this;
let nodes = root.children;
for (let i = 0; i < nodes.length; i++) {
let node = nodes[i];
if (node.children.length) {
this._compile(node);
}
if (node.hasAttribute("v-click")) {
node.onclick = (function () {
let attrVal = nodes[i].getAttribute("v-click");
return _this.$methods[attrVal].bind(_this.$data);
})();
}
if (
node.hasAttribute("v-model") &&
(node.tagName === "INPUT" || node.tagName === "TEXTAREA")
) {
node.addEventListener(
"input",
(function (key) {
let attrVal = nodes[i].getAttribute("v-model");
_this._binding[attrVal]._directives.push(
new Watcher("input", node, _this, attrVal, "value")
);
return function () {
_this.$data[attrVal] = nodes[key].value;
};
})(i)
);
}
if (node.hasAttribute("v-bind")) {
let attrVal = nodes[i].getAttribute("v-bind");
_this._binding[attrVal]._directives.push(
new Watcher("text", node, _this, attrVal, "innerHTML")
);
}
}
}
}
class Watcher {
constructor(name, el, vm, exp, attr) {
this.name = name; // 指令名
this.el = el; // 指令对应dom
this.vm = vm; // 指令所属实例
this.exp = exp; // 指令对应值
this.attr = attr; // 绑定属性值
this.update();
}
update() {
this.el[this.attr] = this.vm.$data[this.exp];
}
}
var app = new MyVue({
el: "#app",
data: {
number: 0
},
methods: {
increment() {
this.number++;
}
}
});
</script>
</html>
以上是脚本宝典为你收集整理的创建MVVM框架全部内容,希望文章能够帮你解决创建MVVM框架所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。