proxy vue3.0

  1 <html>
  2   <head>
  3     <meta charset="UTF-8" />
  4     <meta
  5       name="viewport"
  6       content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
  7     />
  8     <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  9     <title>proxyVue</title>
 10     <style>
 11         #app {
 12             margin: 100px auto 0 auto;
 13             width: 300px;
 14         }
 15         #btn {
 16             margin: 10px auto;
 17         }
 18     </style>
 19   </head>
 20   <body>
 21     <div id="app">
 22       <input type="text" v-model="num" />
 23       <input id="btn" type="button" value="添加到Todolist" v-click="addList" /><br/>
 24       <span>您输入的是:</span><span v-bind="num"></span>
 25       <ul id="list"></ul>
 26     </div>
 27   </body>
 28 
 29   <script>
 30     class proxyVue {
 31       constructor(options) {
 32         this.$options = options || {};
 33         this.$methods = this._methods = this.$options.methods;
 34         const data = (this._data = this.$options.data);
 35         this.subscribe = {};
 36         this.observe(data);
 37         this.compile(options.el);
 38       }
 39       publish(watcher) {
 40         if (!this.subscribe[watcher.property])
 41           this.subscribe[watcher.property] = [];
 42         this.subscribe[watcher.property].push(watcher);
 43       }
 44       observe(data) {
 45         const that = this;
 46         let handler = {
 47           get(target, property) {
 48             return target[property];
 49           },
 50           set(target, property, value) {
 51             let res = Reflect.set(target, property, value);
 52             that.subscribe[property].map(item => {
 53               item.update();
 54             });
 55             return res;
 56           }
 57         };
 58         this.$data = new Proxy(data, handler);
 59       }
 60       compile(el) {
 61         const nodes = Array.prototype.slice.call(
 62           document.querySelector(el).children
 63         );
 64         let data = this.$data;
 65         nodes.map(node => {
 66           if (node.children.length > 0) this._complie(node);
 67           if (node.hasAttribute("v-bind")) {
 68             let property = node.getAttribute("v-bind");
 69             this.publish(new Watcher(node, "innerHTML", data, property));
 70           }
 71           if (node.hasAttribute("v-model")) {
 72             let property = node.getAttribute("v-model");
 73             this.publish(new Watcher(node, "value", data, property));
 74             node.addEventListener("input", () => {
 75               data[property] = node.value;
 76             });
 77           }
 78           if (node.hasAttribute("v-click")) {
 79             let methodName = node.getAttribute("v-click");
 80             let mothod = this.$methods[methodName].bind(data);
 81             node.addEventListener("click", mothod);
 82           }
 83         });
 84       }
 85     }
 86     class Watcher {
 87       constructor(node, attr, data, property) {
 88         this.node = node;
 89         this.attr = attr;
 90         this.data = data;
 91         this.property = property;
 92       }
 93       update() {
 94         this.node[this.attr] = this.data[this.property];
 95       }
 96     }
 97     // 渲染todolist列表
 98     const Render = {
 99       // 初始化
100       init: function(arr) {
101         const fragment = document.createDocumentFragment();
102         for (let i = 0; i < arr.length; i++) {
103           const li = document.createElement("li");
104           li.textContent = arr[i];
105           fragment.appendChild(li);
106         }
107         list.appendChild(fragment);
108       },
109       addList: function(val) {
110         const li = document.createElement("li");
111         li.textContent = val;
112         list.appendChild(li);
113       }
114     };
115     // 实例化一个proxyVue
116     window.onload = function() {
117       let vm = new proxyVue({
118         el: "#app",
119         data: {
120           num: 0,
121           arr: []
122         },
123         methods: {
124           addList() {
125             this.arr.push(this.num);
126             Render.addList(this.num);
127           }
128         }
129       });
130     };
131   </script>
132 </html>
133 摘自https://github.com/nightzing/vue3-Proxy/blob/master/proxyVue.html
134   

 

posted @ 2018-12-20 11:19  疾风_剑豪  阅读(298)  评论(0编辑  收藏  举报