Vueでのテンプレートレンダリングの原理

15988 ワード

Vueでのテンプレートレンダリングの原理
1、概念
  • テンプレート:本質文字列.
  • と文字列の違い:
  • 論理(vueにv-if、v-forがある)
  • 埋め込みjs変数({{変数}})
  • はhtmlに変換する必要があり、ページが認識され、正しく解析されます.

  • 2、実現過程
  • プロセス:テンプレート(文字列)はrender関数----> render関数がJSに戻るvnodeを実行する構造を解析し、埋め込み変数と実行ロジックをどのように実現するか.htmlに変換するとupdateComponent関数呼び出しpatchメソッドによって実現されます.
  • 例1(js変数のみ、論理なし):
  •   <div id="app">
        <p>{{price}}p>
      div>
    
  • vueテンプレートによって生成された結果(テンプレートがJSのvnodeに変換され、dataの変数が埋め込まれることを実現):
  • //   vm VUE   
    //        vm._c     ,vm_v      ,vm_s          
    vm._c(
            'div',
            {
              attrs: {'id': 'app'}
            },
            [
              vm._c('p', [vm._v(vm._s(vm.price))])
            ]
          )
    

    使用法コメント:
  • vm._cはsnabbdomにおけるh(‘ノードラベル’,{属性,特性,イベント},[サブノード]/テキスト)に基づいて実現され,vnodeを作成するために用いられる.vueのrender関数は、Vueインスタンスを入力してvnodeを返す機能を実現します.
  • vm._vは、テキストノードを作成したり、改行を実装したりするために使用されます.
  • vm._sは文字列を変換するために使用されます.
  • render内部は実際にwith(vm)を使用しており、内部で直接使用できるようになっています.c、_v、_sおよびdataのプロパティ
  • 例2(todolistを例にv-for論理を含む):
  •   <div id="app">
        <div>
          <input v-model="inputValue" type="text" />
          <button v-on:click="handleClick">submitbutton>
        div>
        <div>
          <ul>
            <li v-for='item of list'>
              {{item}}
            li>
          ul>
        div>
      div>
    
  • v-for論理実装はv.l()メソッドは,対応するli構造を生成して配列を返し,この配列をulノードのサブノードとする.返されるvnode:
  • with(vm) {
          _c(
            //    (   )div
            'div',
            {
              attrs:{"id":"app"}
            },
            //           
            [
              _c(
                //       div(  input、button   attrs、       )
               'div',
               [
                 _c(
                     'input',
                     {
                      //  v-model       
                       directives:[
                         {
                           name:"model",
                           rawName:"v-model",
                           value:(inputValue),
                           expression:"inputValue"
                          }
                        ],
                       attrs:{
                         "type":"text"
                        },
                       domProps:{
                         "value":(inputValue)
                        },
                       on:{
                        //   input  ,     , Model      
                         "input":function($event){
                           if($event.target.composing)return;
                           inputValue=$event.target.value
                          }
                        }
                      }
                    ),
                   _v(" "),
                   _c(
                       'button',
                       {
                        //       
                         on:{
                           "click":handleClick
                          }
                        },
                       [_v("submit")]
                      )
                ]),
              _v(" "),//       ,    
              _c(
                //       div(  ul、li,  li   for     )
                'div',
                  [
                    _c(
                      // ul  
                      'ul',
                      // _l            
                      _l((list),function(item){
                        // v-for  ,         li     
                        return _c(
                          'li',
                          [
                            _v("
    "
    +_s(item)+"
    "
    ) ] ) }),0)// list , li ] ) ] )} }

    3、まとめ:
  • 個人理解(誤りがあれば訂正を歓迎):1、テンプレート解析render関数----> JSシミュレーションの仮想DOM構造を返す:テンプレートは文字列であり、テンプレート解析はrender関数を生成し、render関数を実行してvnodeに戻る.vnodeは各ノードの階層関係、特性、スタイル、バインドのイベントを示す.2、vnode ----> html:updateComponent関数呼び出しvm._update()によりvnodeに転送され、snabdomベースのpatch()メソッドで改造されたリアルDOMノードを生成し、ページをレンダリングする.注意:vm.__patch__:初回レンダリング時にvm.__patch__(containe, vnode)を呼び出し、実際のDOM構造を生成してコンテナにレンダリングします.re-renderの場合、呼び出しvm.__patch__(vnode, newVnode)はdiffアルゴリズムを用いて新旧vnode間の差異を比較し、更新が必要なリアルDOMを生成し、コンテナの対応する位置にレンダリングする.