前面幾節都是jquery界面方面的東西,本節研究些數據方面的東西:MVVM。javascript
MVVM由三部分組成:Model <=> ViewModel <=> View,當Model數據改變時,通知全部與Model關聯的View進行數據更新。html
以vuejs一個簡單例子實現爲例:vue
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 測試實例</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> </head> <body> <div id="app"> <p>{{ message }}</p> </div> <script> new Vue({ el: '#app', data: { message: 'Hello Vue.js!' } }) </script> </body> </html>
顯示效果以下
java
如今模擬實現這一過程,ES5,6語法之前也沒怎麼接觸,在網上翻看大神的資料,看到一篇實現相對較完整的
https://segmentfault.com/a/1190000016236834jquery
根據他的實現原理本文進行了簡化,只模擬實現綁定過程(不能拿來用於生產環境),稍微有點javascript基礎的應該都能看懂。下次面試時面試官問你原理你說能夠手寫一個。面試
網上許多文章都是觀察者,訂閱者一堆名詞,把讀者都看暈了,其實核心代碼就像下面這段代碼這麼簡單.segmentfault
<body> <div id="app"> <p>{{ message }}</p> <p>{{ message1 }}</p> </div> <div id="log"></div> <script> class JMVVM { constructor(p_obj) { this.init(p_obj); } init(p_obj) { $("#log").append("獲取綁定對象初始化數據信息</br>"); this.element = document.querySelector(p_obj.el); this.data = p_obj.data; $("#log").append("el:" + this.element.id + "</br>"); for (let key in this.data) { let val = this.data[key]; $("#log").append("key:" + key + "</br>"); $("#log").append("一、給對象建立get,set方法</br>"); let element=this.element; Object.defineProperty(this.data, key, { configurable: true, enumerable: true, get() { return val; }, set(newVal) { val = newVal; let reg = eval("/{{([^}]*) "+key+" }}/g"); // let reg1 = /{{([^}]*) +key+ }}/g; let match; $("#log").append("二、替換模板</br>");//模擬,只查找一級。 element.childNodes.forEach(childNode=>{ while ((match = reg.exec(childNode.textContent))) { childNode.textContent=val; } }) // $("#log").append("二、替換模板</br>"); // for(let children in element.childNodes) // while ((match = reg.exec(children.textContent))) { // children.textContent=val; // } } });
//觸發set this.data[key] =val; } } } </script> <script> // new Vue({ // el: "#app", // data: { // message: "Hello Vue.js!" // } // }); new JMVVM({ el: "#app", data: { message1: "Hello JMVVM.js!" } }); </script> </body>
執行結果以下
瀏覽器
上面寫法比較簡單,只能替換一次,由於替換後{{ message }}就不存在了,那麼就應該在第一次替換成功時候將對應元素緩存下來,具體怎麼實現有多種方法,若是理解的不對,歡迎你們指正。緩存
演示地址:www.jgui.comapp
註釋:
ES6 新增了let
命令,用來聲明局部變量。它的用法相似於var
,可是所聲明的變量,只在let
命令所在的代碼塊內有效,並且有暫時性死區的約束。
後續:ES6對IE兼容性挺差的,若是是客戶習慣使用低版本IE的話,儘可能不要使用ES6或者讓客戶更換瀏覽器。