簡(jiǎn)單手寫小白氏理解vue雙向綁定原理

image.png

一個(gè)input袱耽,一個(gè)按鈕死遭,一個(gè)顯示值鞠眉,把大象裝冰箱,總共分三步:
(1) 一個(gè)input,用v-model指令實(shí)現(xiàn)雙向數(shù)據(jù)綁定(1.改變number數(shù)據(jù),template input框值跟著變嫉沽。2.input框值改變辟犀,number數(shù)據(jù)變)
(2) 一個(gè)button,用v-on:click 實(shí)現(xiàn)綁定事件(解析指令,綁定click監(jiān)聽事件)
(3) 一個(gè)h3绸硕,用v-bind和 {{ }} 實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)監(jiān)聽(引用number的template都跟著改變)

<html>
    <div id="app">
      <form>
        <input type="text" v-model="number">
        <button type="button" v-on:click="increment">增加</button>
      </form>
      <h3 v-bind:title="number">{{number}}</h3>
    </div>
    <script>
      // 我理解當(dāng)存儲(chǔ)容器了 key是data的每個(gè)屬性, value是_directives數(shù)組
      // 放著 complie dom后的依賴屬性的每個(gè)節(jié)點(diǎn)信息, 用來監(jiān)聽set屬性值改變后, 更新dom節(jié)點(diǎn)值
      var _binding = {};
      this.init();

      // 初始化
      function init() {
        // data
        this.obj = {
          number: 0
        };
        this.observe();
        this.complie(document.querySelector("#app"));
      };

      /*
       * _observe方法劫持data對(duì)象里的屬性, 每個(gè)屬性重寫set方法, 這個(gè)屬性值改變時(shí)候觸發(fā)set方法,
       *  去_binding里找這個(gè)屬性key,更新complie時(shí)訂閱的dom節(jié)點(diǎn)值
       */
      function observe() {
        _this = this;
        for (const key in obj) {
          if (obj.hasOwnProperty(key)) {
            console.log(this._binding)
            this._binding[key]= {
            _directives : []
          }
          value = obj[key];
          // 劫持get堂竟、set方法
          Object.defineProperty(obj, key, {
            get: function () {
              console.log('get被調(diào)用');
              return value;
            },
            set: function (newValue) {
              console.log('set被調(diào)用,newValue:' + newValue);
              value = newValue;
              // 通知訂閱者 改變節(jié)點(diǎn)
              console.log(_this._binding);
              if (_this._binding[key]) {
                _this._binding[key]._directives.forEach(dir => {
                  [dir.el][0][dir.attr] = value;
                });
              }
            }
          })
        }

      };
    }

      /**
       * complie解析模板DOM指令 放入_binding 訂閱依賴
       * (就是哪塊dom依賴哪個(gè)值,key value 形式存進(jìn)放入_binding{}里)
       */
      function complie(root) {
        let _this = this;
        let nodes = root.children;
        console.log(nodes);
        for (let index = 0; index < nodes.length; index++) {
          const element = nodes[index];
          console.log(element)
          if (element.children.length) {
            this.complie(element);
          }

          // 解析v-on:click
          if (element.hasAttribute('v-on:click')) {
            console.log('hasAttribute:v-on:click')
            element.addEventListener('click', function () {
              console.log('click');
              _this.increment();
            }, false)
          }

          // 解析v-model
          if (element.hasAttribute('v-model')) {
            console.log('hasAttribute:v-model');
            let attrVal = element.getAttribute('v-model');
            // 監(jiān)聽input框輸入值時(shí) 改變屬性值
            element.addEventListener('input', function(key) {
              console.log('監(jiān)聽input值:' + element.value);
              _this.obj[attrVal] = element.value;
            })
            this._binding[attrVal]._directives.push({el: element, attr: 'value', _this: _this});
          }

          // 解析innerHtml,替換{{}}里面的數(shù)據(jù)
          if (element.innerHTML) {
            console.log('innerHtml: {{}}');
            console.log(element.innerHTML);
            let innerHTMLStr = element.innerHTML;
            var matchReg = /(?<={{).*?(?=})/g;
            if (innerHTMLStr.match(matchReg)) {
              for (let attrVal of innerHTMLStr.match(matchReg)) {
                this._binding[attrVal]._directives.push({ el: element, attr: 'innerHTML', _this: _this });
              }
            }
          }
        }
      }

      function increment() {
        obj.number++;
      }
    </script>
</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末玻佩,一起剝皮案震驚了整個(gè)濱河市出嘹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咬崔,老刑警劉巖疚漆,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡娶聘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門甚脉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來丸升,“玉大人,你說我怎么就攤上這事牺氨〗瞥埽” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵猴凹,是天一觀的道長(zhǎng)夷狰。 經(jīng)常有香客問我,道長(zhǎng)郊霎,這世上最難降的妖魔是什么沼头? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮书劝,結(jié)果婚禮上进倍,老公的妹妹穿的比我還像新娘。我一直安慰自己购对,他們只是感情好猾昆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著骡苞,像睡著了一般垂蜗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上解幽,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天贴见,我揣著相機(jī)與錄音,去河邊找鬼亚铁。 笑死蝇刀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的徘溢。 我是一名探鬼主播吞琐,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼然爆!你這毒婦竟也來了站粟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤曾雕,失蹤者是張志新(化名)和其女友劉穎奴烙,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡切诀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年揩环,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幅虑。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丰滑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出倒庵,到底是詐尸還是另有隱情褒墨,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布擎宝,位于F島的核電站郁妈,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏绍申。R本人自食惡果不足惜噩咪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望失晴。 院中可真熱鬧剧腻,春花似錦、人聲如沸涂屁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拆又。三九已至儒旬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間帖族,已是汗流浹背栈源。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留竖般,地道東北人甚垦。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像涣雕,于是被迫代替她去往敵國(guó)和親艰亮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容