VueのRender関数

VueのRender関数

1. ノード、ツリー、仮想DOM

<div>
  <h1>私のタイトル</h1>
  テキストコンテンツ
  <!-- TODO: タグラインを追加 -->
</div>

各要素はノードです。テキストの各段落もノードです。コメントもノードです。ノードはページのセクションです。家系図と同じように、各ノードには子ノードが存在する可能性があります (つまり、各部分に他の部分を含めることができます)。

これらすべてのノードを効率的に更新するのは難しい場合がありますが、幸いなことに手動で行う必要はありません。 Vue にページ上の HTML をどのようにしたいかを伝えるだけで、テンプレートで指定できます。

<h1>{{ ブログタイトル }}</h1>

またはレンダリング関数では:

レンダリング: 関数 (createElement) {
  createElement('h1', this.blogTitle) を返します
}

どちらの場合も、blogTitle が変更されても、Vue は自動的にページを更新し続けます。

2. 仮想DOM

Vue は、実際の DOM がどのように変更されるかを追跡するために仮想 DOM を作成します。次のコード行をよく見てください:

createElement('h1', this.blogTitle) を返します

createElement具体的に何を返すのでしょうか?実際には実際の DOM 要素ではありません。より正確な名前はcreateNodeDescriptionかもしれません。これは、そこに含まれる情報が、子ノードの説明情報を含め、ページにレンダリングする必要があるノードの種類を Vue に伝えるためです。このようなノードは「 virtual node 」と呼ばれ、多くの場合「 VNode 」と略されます。 「仮想 DOM」とは、Vue コンポーネント ツリーによって構築される VNode ツリー全体のことです。

// @returns {VNode}
要素を作成します(
  // {文字列 | オブジェクト | 関数}
  // HTML タグ名、コンポーネント オプション オブジェクト、または // 上記のいずれかに解決される非同期関数。必須フィールドです。
  'div',

  // {物体}
  // テンプレート内の属性に対応するデータ オブジェクト。オプション。
  {
    // (詳細は次のセクションを参照)
  },

  // {文字列 | 配列}
  // `createElement()` によって構築された子仮想ノード (VNode)、
  // 文字列を使用して「テキスト仮想ノード」を生成することもできます。オプション。
  [
    「まずはテキストを書いてください」
    createElement('h1', '見出し'),
    要素を作成します(MyComponent, {
      小道具: {
        いくつかのプロパティ: 'foobar'
      }
    })
  ]
)

2.1 データオブジェクトの詳細

レンダリング関数では、一部のテンプレート属性には Vnode データ オブジェクトの最上位フィールドがあり、通常の属性やinnerHTML (v-html ディレクティブをオーバーライド) などのDOM propertyへのバインドも可能になります。

{
  // `v-bind:class` と同じ API、
  // 文字列、オブジェクト、または文字列とオブジェクトの配列を受け入れます 'class': {
    foo: 真、
    バー: 偽
  },
  // `v-bind:style` と同じ API、
  // 文字列、オブジェクト、またはオブジェクトの配列を受け入れます style: {
    色: '赤'、
    フォントサイズ: '14px'
  },
  // 通常の HTML 属性
  属性: {
    id: 'foo'
  },
  // コンポーネントプロパティ
  小道具: {
    myProp: 'バー'
  },
  // DOMプロパティ
  domProps: {
    内部HTML: 'baz'
  },
  // イベントリスナーは`on`内にあります。
  // ただし、`v-on:keyup.enter` のような修飾子はサポートされなくなりました。
  // 処理関数で keyCode を手動で確認する必要があります。
  の上: {
    クリック: this.clickHandler
  },
  // コンポーネント内で `vm.$emit` によってトリガーされるイベントではなく、ネイティブ イベントをリッスンするコンポーネントにのみ使用されます。
  ネイティブオン: {
    クリック: this.nativeClickHandler
  },
  // カスタムディレクティブ。 `binding` では `oldValue` を使用できないことに注意してください。
  // 割り当て。Vue によって自動的に同期されるためです。
  ディレクティブ: [
    {
      名前: 'my-custom-directive',
      値: '2'、
      式: '1 + 1'、
      引数: 'foo',
      修飾子:
        バー: 真
      }
    }
  ]、
  // スコープ付きスロットの形式は // { name: props => VNode | Array<VNode> } です
  スコープスロット: {
    デフォルト: props => createElement('span', props.text)
  },
  // コンポーネントが別のコンポーネントのサブコンポーネントである場合、スロットの名前を指定する必要があります slot: 'name-of-slot'、
  // その他の特別なトップレベルプロパティ
  キー: 'myKey',
  参照: 'myRef',
  // レンダリング関数で複数の要素に同じ参照名を適用すると、
  // すると `$refs.myRef` は配列になります。
  参照先: true
}

2.2 制約

VNode は一意である必要があります

コンポーネント ツリー内のすべてのVNode一意である必要があります。つまり、次のレンダリング関数は不正です。

レンダリング: 関数 (createElement) {
  var myParagraphVNode = createElement('p', 'hi')
  createElement('div', [ を返します。
    // エラー - VNode が重複しています
    myParagraphVNode、myParagraphVNode
  ])
}

要素/コンポーネントを何度も繰り返す必要がある場合は、ファクトリ関数を使用してそれを実行できます。たとえば、次のレンダリング関数は、20 個の同一の段落を完全に合法的な方法でレンダリングします。

レンダリング: 関数 (createElement) {
  createElement('div', を返します。
    Array.apply(null, { 長さ: 20 }).map(関数 () {
      createElement('p', 'hi') を返します
    })
  )
}

3. レンダリング機能のテンプレート機能

3.1 v-if と v-for

ネイティブJavaScriptで簡単に実行できる限り、 Vueのレンダリング関数は独自の代替手段を提供しません。たとえば、テンプレートで使用されるv-ifv-forです。

<ul v-if="アイテムの長さ">
  <li v-for="item in items">{{ item.name }}</li>
</ul>
<p v-else>アイテムが見つかりません。</p>

これらはすべて、 JavaScriptif/elsemapを使用してレンダリング関数内で書き換えることができます。

プロパティ: ['アイテム'],
レンダリング: 関数 (createElement) {
  if (this.items.length) {
    createElement('ul', this.items.map(function (item) { を返します。
      createElement('li', item.name) を返します。
    }))
  } それ以外 {
    return createElement('p', 'アイテムが見つかりません。')
  }
}

3.2 vモデル

レンダリング関数にはv-modelに直接対応するものはありません。対応するロジックを自分で実装する必要があります。

プロパティ: ['値'],
レンダリング: 関数 (createElement) {
  var 自己 = これ
  createElement('input', を返す)
    domProps: {
      値: 自己.値
    },
    の上: {
      入力: 関数 (イベント) {
        self.$emit('input', イベントターゲット値)
      }
    }
  })
}

これは低レベルになることの代償ですが、 v-modelよりも相互作用の詳細をより細かく制御できます。

3.3 イベントとキー修飾子

passivecapture 、および .once イベント修飾子の場合、Vue はonceの場合に使用できる対応するプレフィックスを提供します。

例えば:

の上: {
  '!click': this.doThisInCapturingMode、
  '~keyup': this.doThisOnce、
  '~!マウスオーバー': this.doThisOnceInCapturingMode
}

他のすべての修飾子の場合、イベント ハンドラー内からイベント メソッドを使用できるため、プライベート プレフィックスは必要ありません。


すべての修飾子を使用した例を次に示します。

の上: {
  keyup: 関数 (イベント) {
    // イベントをトリガーする要素がイベントがバインドされている要素でない場合は、 // 戻ります if (event.target !== event.currentTarget) 戻ります
    // Enter キーが押されなかった場合、または // Shift キーが同時に押されなかった場合 // 戻ります if (!event.shiftKey || event.keyCode !== 13) 戻ります
    // イベントのバブリングを停止する event.stopPropagation()
    // 要素のデフォルトのキーアップイベントを防止します。event.preventDefault()
    // ...
  }
}

3.4 スロット

this.$slotsを介して静的スロットの内容にアクセスできます。各スロットはVNodeの配列です。

レンダリング: 関数 (createElement) {
  // `<div><スロット></スロット></div>`
  createElement('div', this.$slots.default) を返します
}

this.$scopedSlotsを通じてスコープ スロットにアクセスすることもできます。各スコープ スロットは、いくつかのVNodeを返す関数です。

プロパティ: ['メッセージ'],
レンダリング: 関数 (createElement) {
  // `<div><スロット:text="メッセージ"></スロット></div>`
  createElement('div', [ を返します。
    this.$scopedSlots.default({
      テキスト: this.message
    })
  ])
}

レンダリング関数を使用してスコープ スロットを子コンポーネントに渡す場合は、 VNodeデータ オブジェクトのscopedSlotsフィールドを使用できます。

レンダリング: 関数 (createElement) {
  // `<div><child v-slot="props"><span>{{ props.text }}</span></child></div>`
  createElement('div', [ を返します。
    要素を作成します('child', {
      // データオブジェクトに `scopedSlots` を渡す
      // 形式は { name: props => VNode | Array<VNode> } です
      スコープスロット: {
        デフォルト: 関数 (props) {
          createElement('span', props.text) を返します。
        }
      }
    })
  ])
}

3.5 例

'vue/types/umd' から { CreateElement, RenderContext } をインポートします。

エクスポートデフォルト{
  機能的: 真、
  小道具: {
    行: オブジェクト、
    レンダリング: 関数、
    インデックス: 番号、
    カラム: {
      タイプ: オブジェクト、
      デフォルト: null
    }
  },
  レンダリング: (h: CreateElement, ctx: RenderContext) => {
    定数パラメータ: 任意 = {
      行: ctx.props.row、
      インデックス: ctx.props.index
    }
    if (ctx.props.column) params.column = ctx.props.column
    ctx.props.render(h, params) を返す
  }
}

vueRender機能に関する記事はこれで終わりです。より関連性の高いRender機能のコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • VUE レンダリング機能の使い方と詳細な説明
  • Vue.jsのレンダリング関数の使い方の詳しい説明
  • Vue のレンダリング関数を使用してサブコンポーネントの参照操作を設定する
  • Vue レンダリング関数は img の src パス操作を動的に読み込みます
  • Vue Render関数の原理とコード例の分析
  • Vueのレンダリング機能の詳細な説明
  • レンダリング関数を使用して、拡張性の高いコンポーネントをカプセル化する

<<:  Tomcatの動作原理を分析する

>>:  Dockerバッチコンテナオーケストレーションの実装

推薦する

フロントエンドとバックエンド分離プロジェクトのDockerデプロイメントの実装例

目次1. 環境整備2. イメージを実行する問題を解決するRedis のインストールNginx のイン...

Dockerイメージのエクスポートとインポート操作

基本イメージが以前に構成されていて、これらのイメージが他の場所でも必要な場合はどうなりますか?回答:...

JavaScriptの知識ポイントの詳しい説明

目次1. JavaScriptの基礎2. 基本的なJavaScript構文3. JavaScript...

Vue computedのキャッシュ実装原理の詳細な説明

目次計算結果を初期化する依存関係の収集アップデートを配布する総括するこの記事では、計算された初期化と...

sqlalchemy に基づいて MySQL で追加、削除、変更、クエリ操作を実装する

需要シナリオ:上司は、クロ​​ーラーを使用してMySQLデータベースにデータを書き込んだり更新したり...

仮想マシンUbuntu 16.04がインターネットに接続できない問題の解決策

Ubuntu をインストールしたばかりですが、開いたときにネットワーク接続がありませんでした。右上隅...

フローティングをクリアするいくつかの方法(推奨)

1. 同じタイプの空の要素を追加し、要素の CSS 属性 clear:both; を設定します。 ...

VMwareがLinuxシステムをインストールして起動した後に黒い画面が表示される問題を解決する

1. 設置環境1. HUAWEI mate x CPU i5 82500u、8g メモリ、独立グラフ...

JSはjQueryのappend関数を実装します

目次コードを見せてください効果をテストする効果追伸別のアプローチコードを見せてください HTMLEl...

Vue3ナビゲーションバーコンポーネントのカプセル化実装方法

参考までに、Vue3でナビゲーションバーコンポーネントをカプセル化し、スクロールバーのスクロールに合...

停止したすべてのDockerコンテナを1つのコマンドで再起動する

停止したすべてのDockerコンテナを1つのコマンドで再起動するdocker ps -a | gre...

MySQL InnoDB MRR 最適化ガイド

序文MRR は Multi-Range Read の略で、ランダム ディスク アクセスを削減し、ラン...

Vue フロントエンド開発における keepAlive の使用方法の詳細な説明

目次序文keep-avlive フック関数keep-avliveはどのコンポーネントをキャッシュする...

React スキャフォールディングのパスエイリアスを設定する方法

この記事を書いている時点でのReactのバージョンは16.13.1です1 npm run eject...

MySQL 8.0.17 のインストールと使用方法のチュートリアル図

前面に書かれた過去および現在のプロジェクトで最も一般的に使用されているリレーショナル データベースは...