1. 程式人生 > 其它 >Vue原始碼分析[1][模擬插值語法]

Vue原始碼分析[1][模擬插值語法]

1.單檔案的時候會使用到mount函式進行掛載

模擬插值語法

  <div id="app">
    <p>{{name}}{{fff}}</p>
    <p>{{message}}</p>
  </div>
  //1.獲取DOM
  let tempNode = document.querySelector('#app');
  //正則表示式裡 花括號是有特殊含義的 因此我們要對花括號進行轉義
  //.+表示裡邊可以匹配任意的字元 ? 表示取消貪婪
  //加圓括號,目的是通過正則將括號內的字元取出來
  //g代表全域性模式
  let regular = /\{\{(.+?)\}\}/g

  //2.建立變數
  var data = {
      name:'zs',
      message: "abc",
      fff:'hahaha'
  };
  //3.將資料放入模板
  //Vue原始碼中DOM->字串模板->抽象語法樹->真正的DOM
  //在本文件中,我們暫時使用真正的DOM元素
  function compiler(template,data){
    let childNodes = template.childNodes;
    for(let i = 0 ; i < childNodes.length; i++){
      let type = childNodes[ i ].nodeType;
      //檢視子節點的型別 1 元素 3 文字節點
      if( type === 3 ) {
        let text = childNodes[ i ].nodeValue;

        //使用replace方法,將正則表示式替換為我們需要的

        /*
        replace是一個字串的方法,可接受兩個引數
        分兩種情況
        1.接受兩個字串,使用param1替換String中的param2,返回一個全新替換後的String
        2.接受param1為正則表示式,param2為回撥函式,正則每匹配到一次,呼叫一次回撥函式
        */

        //將替換後的結果重新賦給節點
        text = text.replace(regular , function ( _ , g){

          //取到的值剛好是data裡的屬性
          let key = g.trim();
          let value = data[ key ];
          return value
        })
        childNodes[ i ].nodeValue = text
        //這裡有嘗試過下面的方式,以為會更便捷,但是沒有考慮到{{}}有很多組的情況,所以必須得到新的text然後將這個整體全部替換掉
        /*
        text.replace(regular , function ( _ , g){
          let key = g.trim();
          childNodes[ i ].nodeValue  = data[ key ];
        })
        */
        
        //trim方法
        /*
        trim() 方法會從一個字串的兩端刪除空白字元。在這個上下文中的空白字元是所有的空白字元 (space, tab, no-break space 等) 以及所有行終止符字元(如 LF,CR等)。

        */
      }
      else if ( type === 1 ) {
        compiler( childNodes[ i ], data );
      }
    }
  }
  console.log(tempNode);
  //dom是引用型別,所以需要重新深拷貝一份node
  operateNode = tempNode.cloneNode(true);
  compiler(operateNode , data);
  console.log(operateNode);
  app.parentNode.replaceChild(operateNode , app)