<html>
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>proxyVue</title>
<style>
#app {
margin: 100px auto 0 auto;
width: 300px;
}
#btn {
margin: 10px auto;
}
</style>
</head>
<body>
<div id="app">
<input type="text" v-model="num" />
<input id="btn" type="button" value="添加到Todolist" v-click="addList" /><br/>
<span>您输入的是:</span><span v-bind="num"></span>
<ul id="list"></ul>
</div>
</body> <script>
class proxyVue {
constructor(options) {
this.$options = options || {};
this.$methods = this._methods = this.$options.methods;
const data = (this._data = this.$options.data);
this.subscribe = {};
this.observe(data);
this.compile(options.el);
}
publish(watcher) {
if (!this.subscribe[watcher.property])
this.subscribe[watcher.property] = [];
this.subscribe[watcher.property].push(watcher);
}
observe(data) {
const that = this;
let handler = {
get(target, property) {
return target[property];
},
set(target, property, value) {
let res = Reflect.set(target, property, value);
that.subscribe[property].map(item => {
item.update();
});
return res;
}
};
this.$data = new Proxy(data, handler);
}
compile(el) {
const nodes = Array.prototype.slice.call(
document.querySelector(el).children
);
let data = this.$data;
nodes.map(node => {
if (node.children.length > 0) this._complie(node);
if (node.hasAttribute("v-bind")) {
let property = node.getAttribute("v-bind");
this.publish(new Watcher(node, "innerHTML", data, property));
}
if (node.hasAttribute("v-model")) {
let property = node.getAttribute("v-model");
this.publish(new Watcher(node, "value", data, property));
node.addEventListener("input", () => {
data[property] = node.value;
});
}
if (node.hasAttribute("v-click")) {
let methodName = node.getAttribute("v-click");
let mothod = this.$methods[methodName].bind(data);
node.addEventListener("click", mothod);
}
});
}
}
class Watcher {
constructor(node, attr, data, property) {
this.node = node;
this.attr = attr;
this.data = data;
this.property = property;
}
update() {
this.node[this.attr] = this.data[this.property];
}
}
// 渲染todolist列表
const Render = {
// 初始化
init: function(arr) {
const fragment = document.createDocumentFragment();
for (let i = 0; i < arr.length; i++) {
const li = document.createElement("li");
li.textContent = arr[i];
fragment.appendChild(li);
}
list.appendChild(fragment);
},
addList: function(val) {
const li = document.createElement("li");
li.textContent = val;
list.appendChild(li);
}
};
// 实例化一个proxyVue
window.onload = function() {
let vm = new proxyVue({
el: "#app",
data: {
num: 0,
arr: []
},
methods: {
addList() {
this.arr.push(this.num);
Render.addList(this.num);
}
}
});
};
</script>
</html>
摘自https://github.com/nightzing/vue3-Proxy/blob/master/proxyVue.html
  

最新文章

  1. Qtablevies获取内容
  2. Html5+NodeJS——拖拽多个文件上传到服务器
  3. [python]沪深龙虎榜数据导入通达信的自选板块,并标注于K线图上
  4. Unity unsafe
  5. 如何查看apache,php,mysql的编译参数
  6. 实战录 | 一起唠唠那些常见的DDoS攻击
  7. JavaScript学习笔记-自定义滚动条
  8. js的基本数据类型有哪些?
  9. Getting Started With Python Internals
  10. Docker私有仓库Registry 搭建
  11. laravel sql复杂语句,原生写法----连表分组
  12. ANGULAR6.x - 错误随笔 - Can&#39;t bind to &#39;formGroup&#39;
  13. SAP Brazil J1BTAX 为税收例外创建税收组(翻译)
  14. Android下WPS打开Excel2007版也有问题
  15. ERP开源框架 + 二次开发平台 介绍
  16. vue中extend/component/mixins/extends的区别
  17. 状压dp的另一种形式
  18. PHP用正则匹配字符串中的特殊字符防SQL注入
  19. GCC手册学习(序)
  20. 国外物联网平台(4):Ayla Networks

热门文章

  1. rest_framework之渲染器
  2. 线段树-hdu2795 Billboard(贴海报)
  3. Apache 的知识点
  4. Storm事务Topology的接口介绍
  5. B-2阶段组员分数分配
  6. vue.js+vue-router+webpack keep-alive用法
  7. 获取网站图标Icon
  8. 具体数学斯特林数-----致敬Kunth
  9. 【刷题】LOJ 6038 「雅礼集训 2017 Day5」远行
  10. 跟我学Spring Cloud(Finchley版)-17-Zuul路由配置详解