ホームページ > ウェブフロントエンド > Vue.js > Vue の学習でテンプレートのコンパイル原則について語る

Vue の学習でテンプレートのコンパイル原則について語る

青灯夜游
リリース: 2023-03-07 19:01:00
転載
1532 人が閲覧しました

テンプレートのコンパイルとは何ですか?次の記事では、Vue でのテンプレートのコンパイルについて説明し、テンプレートのコンパイルの原則について説明します。

Vue の学習でテンプレートのコンパイル原則について語る

vue は、<p>{{name}} </p> <p dom>。 </p> <p><strong>テンプレートのコンパイルとは、テンプレートがレンダリング関数にコンパイルされるプロセスを指します。レンダリング関数の機能は、毎回最新のステータスに基づいて新しい vnode</strong> を生成することです。実行されました。 </p> <p>コンパイル プロセスは次のとおりです: <code>入力としてのテンプレート -> テンプレートのコンパイル ステージ -> レンダリング関数の生成

#インタビューの質問

  • vue テンプレートのコンパイル?
  • テンプレートコンパイル Compiler でのレンダリングの説明?
  • vue テンプレートのコンパイル プロセス、各プロセスで何が行われるかを詳しく説明します。
  • テンプレートのコンパイル、誰が AST ツリーを解析するか [関連する推奨事項: vuejs ビデオ チュートリアル Web フロントエンド開発]

#テンプレートをレンダリング関数にコンパイルする

Vue の学習でテンプレートのコンパイル原則について語る

    #Parser
  • : テンプレートを AST (抽象構文ツリー) に解析します。
  • Optimizer
  • : AST をトラバースして静的ノードをマークします。ラベル付き静的ノードに新しい仮想ノードを作成する必要はなく、既存の仮想ノードを直接複製できます。
  • コード ジェネレーター
  • : AST を使用してレンダリング関数を生成します。 ASTをコード文字列に変換します。コード文字列をレンダリング関数に入力し、外部で使用できるようにエクスポートします。

#ケース

Vue の学習でテンプレートのコンパイル原則について語る

1. テンプレートの確認 次のコードには

el

templaterender$mount があると仮定します。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">//复杂案例 let vue = new Vue({ el: &amp;#39;#app&amp;#39;, data() { return { a: 1, b: [1] } }, render(h) { return h(&amp;#39;div&amp;#39;, { id: &amp;#39;hhh&amp;#39; }, &amp;#39;hello&amp;#39;) }, template: `&lt;div id=&amp;#39;hhh&amp;#39; style=&quot;aa:1;bb:2&quot;&gt;&lt;a&gt;{{xxx}}{{ccc}}&lt;/a&gt;&lt;/div&gt;` }).$mount(&amp;#39;#app&amp;#39;) console.log(vue) //脚手架创建的案例 let vue = new Vue({ render: h =&gt; h(App) }).$mount(&amp;#39;#app&amp;#39;)</pre><div class="contentsignin">ログイン後にコピー</div></div>

Vue の学習でテンプレートのコンパイル原則について語る

#1) どのルート ノードをレンダリングするか

: el 属性があるかどうかを確認します。ある場合は、el ルート ノードを直接取得します。ない場合は、el ルート ノードを直接取得します。ルート ノード

2) ルート ノードにレンダリングするテンプレート

: テンプレートに渡す render 関数を呼び出すかどうかrender: h => h(App ) -> <App></App>

renderあり: このとき、最初にrender関数が実行されます。 ,
    レンダリング優先度> テンプレート
  • レンダリングなし:
  • テンプレートあり: テンプレートはレンダリング関数の必要な形式 (コード文字列) に解析され、render を使用してレンダリングされます。関数呼び出し
    • テンプレートなし: el ルート ノードを render 関数で必要な形式 (コード文字列) に解析した externalHTML で、render 関数を使用してレンダリングします。
    • 3. レンダリング方法: レンダリング方法は関係ありません。状況に応じて、最後のステップは、
    • レンダリング関数を使用してレンダリングすることです

2. テンプレートをパーサー解析します。 into AST

Parser-parse the template into AST

<div>
  <p>{{name}}</p>
</div>
ログイン後にコピー

上記のテンプレートを AST に解析した後、AST 抽象構文ツリーは、JS 内のオブジェクトを使用してノードと 1 つのオブジェクトを記述します。ノードを表します。

{
  tag: "div"
  type: 1, //节点类型
  staticRoot: false,
  static: false,
  plain: true,
  parent: undefined, //存放父节点
  attrsList: [],
  attrsMap: {},
  children: [ //存放孩子节点
      {
      tag: "p"
      type: 1,
      staticRoot: false,
      static: false,
      plain: true,
      parent: {tag: "div", ...},
      attrsList: [],
      attrsMap: {},
      children: [{
          type: 2,
          text: "{{name}}",
          static: false,
          expression: "_s(name)"
      }]
    }
  ]
}
ログイン後にコピー

パーサーの動作原理

パーサーの原理は、テンプレート文字列を小さなセクションに分けてインターセプトすることです。 time 短い文字列をインターセプトすると、テンプレート文字列がインターセプトされるまで、インターセプトされた文字列のタイプに応じてさまざまなフック関数がトリガーされます。次に、スタックを使用して階層関係を決定します。

パーサーの内部部分は、HTML パーサー、テキスト パーサーなどのいくつかのサブパーサーにも分割されます。

HTML パーサーの役割は HTML を解析することです。HTML を解析する過程で、さまざまなフック関数が継続的にトリガーされます。

    HTML パーサーのフック関数開始タグは、要素タイプのノードの構築が可能です。
  • テキスト タイプのノードは、テキスト フック関数で構築できます。
  • コメント タイプのノードは、コメント フック関数で構築できます。
  • Endタグフック関数
テキスト パーサーは、HTML から解析されたテキストに対して補間構文などの二次処理を実行します

{{}}

方法DOM関係間のレベルを決定しますか?スタックの使用 開始タグのフック関数をトリガーするときに、現在のタグが自己終了タグでない場合、
pushstack に入ります。 終了タグのフック関数がトリガーされると、スタックから
pop が出てきます

3. AST の静的ノードをオプティマイザーでマークします

静的サブツリーをマークする利点

  • 每次重新渲染时,不需要为静态子树创建新虚拟子树,克隆已存在的静态子树
  • 在虚拟DOM中打补丁(patching)的过程可以跳过 ,静态子树是不可变的

优化器的内部实现主要分两步用递归的方式将所有节点添加 static 属性,true表示是静态的,false表示不是静态的。

  • 在AST中找出所有静态节点并打上标记
    静态节点:DOM不会发生变化的节点
    通过递归的方式从上向下标记静态节点,如果一个节点被标记为静态节点,但它的子节点却被标记为动态节点,就说明该节点不是静态节点,可以将它改为动态节点。静态节点的特征是它的子节点也必须是静态的。

静态根节点也是静态节点

  • **在AST中找出所有静态根节点并打上标记 **
    静态根节点:子节点全是静态节点的节点
    使用递归从上向下寻找,在寻找的过程中遇见的第一个静态节点就为静态根节点,同时不继续往下找。

如果一个静态根节点的子节点只有一个文本节点或没有子节点,那么不会标记成静态根节点,即使他们是,因为优化成本大于收益

怎么判断是否静态节点?
在将模板字符串解析成AST的时候,会根据不同的文本类型设置一个 type

type说明是否时静态节点
1元素节点进行一些排除
2带遍历的动态文本节点不是
3不带遍历的纯文本节点

4.代码生成器-将AST转化成渲染函数中的代码字符串

代码生成器的作用:将AST转化成渲染函数中的代码字符串

<div>
  <p>{{name}}</p>
</div>
//生成的render渲染函数
{
  render: `with(this){return _c('div',[_c('p',[_v(_s(name))])])}`
}
//格式化后
with(this){
  return _c(
    'div',
    [
      _c(
        'p',
        [
          _v(_s(name))
        ]
      )
    ]
  )
}
ログイン後にコピー

生成代码字符串是一个递归的过程,从顶向下依次处理每一个AST节点。
节点有三种类型,分别对应三种不同的创建方法与别名。

类型 创建方法 别名
元素节点 createElement _c
文本节点 createTextVNode _v
注释节点 createEmptyVNode _e

渲染函数可以生成VNode的原因:渲染函数其实是执行了createElement,而createElement可以创建VNode。

代码字符串的拼接过程

递归AST来生成字符串,最先生成根节点,然后在子节点字符串生成后,将其拼接在根节点的参数中,子节点的子节点拼接在子节点的参数中,一层层拼接。

(学习视频分享:vuejs入门教程编程基础视频

以上がVue の学習でテンプレートのコンパイル原則について語るの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:csdn.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート