摘要:依賴收集觀察數據添加到中編譯為抽象語法樹這里要簡單得多獲取設置為根節點,傳入的指令名指令對應指令所屬實例指令對應值綁定屬性值
Document
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++; } } });
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/103078.html
摘要:上一篇寫了實現框架的一些基本概念本篇用代碼來實現一個完整的框架思考假設有如下代碼,里面的會和試圖中的一一映射,修改的值,會直接引起試圖中對應數據的變化如何實現上述呢回想下這篇講的觀察者模式和數據監聽主題是什么觀察者是什么觀察者何時訂閱主題主 上一篇寫了實現 MVVM 框架的一些基本概念 本篇用代碼來實現一個完整的 MVVM 框架 思考 假設有如下代碼,data里面的name會和試圖中的...
摘要:小白一枚,一直使用的是,想要多了解一些其它的框架,正好最近越來越火熱,上的數已經超過了。框架理解說起這個模型,就不得不說框架。函數表示創建一個文本節點,函數表示創建一個數組。 小白一枚,一直使用的是React,想要多了解一些其它的框架,正好最近Vue越來越火熱,Github上的Star數已經超過了React。而其背后蘊含的MVVM框架思想也一直跟React的組件化開發思想并駕齊驅,在這...
摘要:在前端頁面中,把用純對象表示,負責顯示,兩者做到了最大化的分離把和關聯起來的就是。了解了思想后,自己用原生實現一個框架。注意數據描述符和存儲描述符不能同時存在,否則會報錯報錯數據攔截使用來實現數據攔截,從而實現數據監聽。 在前端頁面中,把 Model 用純 JS 對象表示,View 負責顯示,兩者做到了最大化的分離 把 Model 和 View 關聯起來的就是 ViewModel。Vi...
摘要:框架的誕生以上便是一個簡短精簡的風格的學生信息的示例。至此,一個精簡的框架其實已經出來了什么你確定不是在開玩笑一個只有十行的框架請記住框架是對如何組織代碼和整個項目如何通用運作的抽象。 前言 MVVM模式相信做前端的人都不陌生,去網上搜MVVM,會出現一大堆關于MVVM模式的博文,但是這些博文大多都只是用圖片和文字來進行抽象的概念講解,對于剛接觸MVVM模式的新手來說,這些概念雖然能夠...
摘要:為了將對象和視圖綁定在一起,我們需要設置一個回調函數,當對象的屬性發生改變時發送一個更新視圖的通知。下面是值發生變化的時候調用的回調函數,當然現在我們可以使用更簡單的進行數據的監聽,這在我們后面的將會講到。 MVC MVC是一種設計模式,它將應用劃分為3個部分:數據(模型)、展示層(視圖)和用戶交互層。結合一下下圖,更能理解三者之間的關系。showImg(https://segment...
閱讀 3399·2021-11-24 09:38
閱讀 1395·2021-11-22 15:08
閱讀 1470·2021-09-29 09:35
閱讀 488·2021-09-02 15:11
閱讀 1312·2019-08-30 12:55
閱讀 395·2019-08-29 17:16
閱讀 499·2019-08-29 11:30
閱讀 426·2019-08-26 13:23