<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      10分鐘了解MVVM,實現簡易MVVM

      MVVM 是 Model-View-ViewModel 縮寫,也就是把 MVC 中的 Controller 演變成 ViewModel。Model 層代表數據模型,View 代表 UI 組件,ViewModel 是 View 和 Model 層的橋梁,數據會綁定到 viewModel 層并自動將數據渲染到頁面中,視圖變化的時候會通知 viewModel 層更新數據。

      1. Model: 代表數據模型,也可以在 Model 中定義數據修改和操作的業務邏輯。我們可以把 Model 稱為數據層,因為它僅僅關注數據本身,不關心任何行為
      2. View: 用戶操作界面。當 ViewModel 對 Model 進行更新的時候,會通過數據綁定更新到 View
      3. ViewModel: 業務邏輯層,View 需要什么數據,ViewModel 要提供這個數據;View 有某些操作,ViewModel 就要響應這些操作,所以可以說它是 Model for View.

      總結: MVVM 模式簡化了界面與業務的依賴,解決了數據頻繁更新。MVVM 在使用當中,利用雙向綁定技術,使得 Model 變化時,ViewModel 會自動更新,而 ViewModel 變化時,View 也會自動變化。

      實現一個簡易的 MVVM 分為這么幾步來

      1.類 Vue:這個類接收的是一個 options。
         el屬性:根元素的id
         data屬性:雙向綁定的數據。
      
      2.Dep 類:
         subNode數組:存放所依賴這個屬性  的依賴,
         addSub方法:添加依賴的
         removeSub方法:刪除,
         updata方法:遍歷更新它subs中的所有依賴
         target靜態屬性:用來表示 '當前的觀察者' ,依賴收集的時候可以將它添加到dep. subNode中
      
      
      
         靜態的是指向類自身,而不是指向實例對象,主要是歸屬不同,這是靜態屬性的核心
      
      3.observe 方法:監聽數據變化(參數:data,也就是 options.data)
         遍歷data:使用Object.defineProperty()來重寫它的get和set,
         使用new Dep():實例化一個dep對象,
         get時:addSub 添加 '當前的觀察者Dep.target' 完成依賴收集,
         set時:dep.updata 通知每一個依賴它的觀察者進行更新
      
      4.compile 方法:來將 HTML 模版和數據結合起來(參數:node 節點)。
         遍歷它的所有子級,判斷是否有firstElmentChild
             有:進行遞歸調用compile方法,
             沒有:child.innderHTML用判斷是否有(/\{\{(.*)\}\}/)需要雙向綁定的數據,
                 有:new Reg('\\{\\{\\s*' + key + '\\s*\\}\\}', 'gm')替換msg變量。
      
      5.將 Dep.target 指向當前的這個 child,
        調用this.opt.data[key]:觸發這個數據的get來對當前的child進行依賴收集,
             目的:下次數據變化通知child進行視圖更新,
         將Dep.target指為null(其實在Vue中是有一個targetStack棧用來存放target的指向的)
      
      6.監聽 document 的 DOMContentLoaded
         回調函數中實例化這個Vue對象就可以了
      

      需要注意的點:

      childNodes 會獲取到所有的子節點以及文本節點(包括元素標簽中的空白節點)
      firstElementChild 表示獲取元素的第一個字元素節點,以此來區分是不是元素節點,如果是的話則調用 compile 進行遞歸調用,否則用正則匹配

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="UTF-8" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <meta http-equiv="X-UA-Compatible" content="ie=edge" />
          <title>MVVM</title>
        </head>
        <body>
          <div id="app">
            <h3>姓名</h3>
            <p>{{name}}</p>
            <h3>年齡</h3>
            <p>{{age}}</p>
          </div>
        </body>
      </html>
      <script>
        document.addEventListener(
          "DOMContentLoaded",
          function () {
            let opt = { el: "#app", data: { name: "等待修改...", age: 20 } };
            let vm = new Vue(opt);
            setTimeout(() => {
              opt.data.name = "jing";
            }, 2000);
          },
          false
        );
        class Vue {
          constructor(opt) {
            this.opt = opt;
            this.observer(opt.data);
            let root = document.querySelector(opt.el);
            this.compile(root);
          }
          observer(data) {
            Object.keys(data).forEach((key) => {
              let obv = new Dep();
              data["_" + key] = data[key];
      
              Object.defineProperty(data, key, {
                get() {
                  Dep.target && obv.addSubNode(Dep.target);
                  return data["_" + key];
                },
                set(newVal) {
                  obv.update(newVal);
                  data["_" + key] = newVal;
                },
              });
            });
          }
          compile(node) {
            [].forEach.call(node.childNodes, (child) => {
              if (!child.firstElementChild && /\{\{(.*)\}\}/.test(child.innerHTML)) {
                let key = RegExp.$1.trim();
                child.innerHTML = child.innerHTML.replace(
                  new RegExp("\\{\\{\\s*" + key + "\\s*\\}\\}", "gm"),
                  this.opt.data[key]
                );
                Dep.target = child;
                this.opt.data[key];
                Dep.target = null;
              } else if (child.firstElementChild) this.compile(child);
            });
          }
        }
      
        class Dep {
          constructor() {
            this.subNode = [];
          }
          addSubNode(node) {
            this.subNode.push(node);
          }
          update(newVal) {
            this.subNode.forEach((node) => {
              node.innerHTML = newVal;
            });
          }
        }
      </script>
      
      posted @ 2023-02-17 11:34  雅痞_yuppie  閱讀(575)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲熟妇自偷自拍另欧美 | 日本人一区二区在线观看| 亚洲香蕉av一区二区蜜桃 | 不卡av电影在线| 亚洲婷婷综合色高清在线| 国产综合色一区二区三区| 人妻另类 专区 欧美 制服| 久久天天躁狠狠躁夜夜avapp| 亚洲av成人一区国产精品| 亚洲精品久久一区二区三区四区| 四虎成人在线观看免费| 人妻日韩人妻中文字幕| 国产精品一二三区蜜臀av| 国产肉丝袜在线观看| 兔费看少妇性l交大片免费| 综合图区亚洲欧美另类图片| 中国老熟女重囗味hdxx| 中日韩黄色基地一二三区| 免费人成视频x8x8国产| 欧美成人精品高清在线播放| 九色综合国产一区二区三区| 日本va欧美va欧美va精品| 国产一区二区三区免费观看| 亚洲国产成人综合自在线| 丰满熟女人妻一区二区三| 中文字幕一区二区久久综合| 成人免费无码大片A毛片抽搐色欲 成人啪精品视频网站午夜 | 好男人好资源WWW社区| 亚洲制服无码一区二区三区| 国产一区二区日韩在线| 天干天干夜啦天干天干国产| 巫山县| 日韩熟妇中文色在线视频| 亚洲欧美日韩成人综合一区 | 中国china体内裑精亚洲日本| 国产亚洲无线码一区二区| 99久久精品久久久久久婷婷| 亚洲а∨精品天堂在线| 人妻精品人妻无码一区二区三区 | 国产99在线 | 欧美| 日韩激情一区二区三区|