JGUI源碼:實現簡單MVVM單項綁定學習筆記(15)

前面幾節都是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或者讓客戶更換瀏覽器。

相關文章
相關標籤/搜索