本文へジャンプ

レンダー関数 API

h()

仮想 DOM ノード(vnode)を作成します。

  • ts
    // 完全なシグネチャー
    function h(
      type: string | Component,
      props?: object | null,
      children?: Children | Slot | Slots
    ): VNode
    
    // props を省略する場合
    function h(type: string | Component, children?: Children | Slot): VNode
    
    type Children = string | number | boolean | VNode | null | Children[]
    
    type Slot = () => Children
    
    type Slots = { [name: string]: Slot }

    読みやすくするため、型は単純化されています。

  • 詳細

    第 1 引数には、文字列(ネイティブ要素の場合)または Vue コンポーネント定義を指定します。第 2 引数は渡される props で、第 3 引数は子要素です。

    コンポーネントの vnode を作成するとき、子要素はスロット関数として渡さなければなりません。コンポーネントがデフォルトのスロットのみを想定している場合、単一のスロット関数を渡すことができます。そうでない場合は、スロットはスロット関数のオブジェクトとして渡さなければなりません。

    便宜上、子要素がスロットオブジェクトでない場合は props 引数を省略できます。

  • ネイティブ要素を作成する:

    js
    import { h } from 'vue'
    
    // type 以外のすべての引数は省略可能
    h('div')
    h('div', { id: 'foo' })
    
    // props は属性とプロパティの両方が使用可能
    // Vue は自動的に適切な方法で割り当てます
    h('div', { class: 'bar', innerHTML: 'hello' })
    
    // テンプレート内と同様、クラスとスタイルは
    // オブジェクトや配列の値をサポートしています
    h('div', { class: [foo, { bar }], style: { color: 'red' } })
    
    // イベントリスナーは onXxx として渡す必要があります
    h('div', { onClick: () => {} })
    
    // children は文字列でも構いません
    h('div', { id: 'foo' }, 'hello')
    
    // props がない場合は省略できます
    h('div', 'hello')
    h('div', [h('span', 'hello')])
    
    // children 配列には vnode と文字列を混在させることができます
    h('div', ['hello', h('span', 'hello')])

    コンポーネントを作成:

    js
    import Foo from './Foo.vue'
    
    // props を渡す
    h(Foo, {
      // some-prop="hello" と同等
      someProp: 'hello',
      // @update="() => {}" と同等
      onUpdate: () => {}
    })
    
    // 単一のデフォルトスロットを渡す
    h(Foo, () => 'default slot')
    
    // 名前付きスロットを渡す
    // スロットオブジェクトが props として扱われないよう
    // `null` が必要なことに注意
    h(MyComponent, null, {
      default: () => 'default slot',
      foo: () => h('div', 'foo'),
      bar: () => [h('span', 'one'), h('span', 'two')]
    })
  • 参照 ガイド - レンダー関数 - vnode の作成

mergeProps()

複数の props オブジェクトをマージします。特定の props には特別な処理があります。

  • ts
    function mergeProps(...args: object[]): object
  • 詳細

    mergeProps() は複数の props オブジェクトのマージをサポートし、以下の props に対して特別な処理を行います:

    • class
    • style
    • onXxx イベントリスナー - 同じ名前の複数のリスナーは、配列にマージされます。

    マージ動作が不要で、単純な上書きでよい場合は、代わりにネイティブオブジェクトのスプレッドを使用できます。

  • js
    import { mergeProps } from 'vue'
    
    const one = {
      class: 'foo',
      onClick: handlerA
    }
    
    const two = {
      class: { bar: true },
      onClick: handlerB
    }
    
    const merged = mergeProps(one, two)
    /**
     {
       class: 'foo bar',
       onClick: [handlerA, handlerB]
     }
     */

cloneVNode()

vnode のクローンを作成します。

  • ts
    function cloneVNode(vnode: VNode, extraProps?: object): VNode
  • 詳細

    クローンした vnode を返します。オリジナルの vnode とマージするための追加の props を含みます。

    vnode は一度作成したらイミュータブルであると考えるべきで、既存の vnode の props を変更するべきではありません。その代わり、別の props /追加の props を使ってクローンしてください。

    vnode は特別な内部プロパティを持っているので、クローンするのはオブジェクトのスプレッドのように単純ではありません。cloneVNode() はその内部ロジックの大部分を処理します。

  • js
    import { h, cloneVNode } from 'vue'
    
    const original = h('div')
    const cloned = cloneVNode(original, { id: 'foo' })

isVNode()

値が vnode かどうかをチェックします。

  • ts
    function isVNode(value: unknown): boolean

resolveComponent()

登録されたコンポーネントを名前によって手動で解決します。

  • ts
    function resolveComponent(name: string): Component | string
  • 詳細

    注意:コンポーネントを直接インポートできる場合は不要です。

    resolveComponent() は、正しいコンポーネントコンテキストから解決するために setup() または レンダー関数の内部で呼び出す必要があります。

    コンポーネントが見つからない場合、実行時警告が発生し、名前の文字列が返されます。

  • js
    import { h, resolveComponent } from 'vue'
    
    export default {
      setup() {
        const ButtonCounter = resolveComponent('ButtonCounter')
    
        return () => {
          return h(ButtonCounter)
        }
      }
    }
    js
    import { h, resolveComponent } from 'vue'
    
    export default {
      render() {
        const ButtonCounter = resolveComponent('ButtonCounter')
        return h(ButtonCounter)
      }
    }
  • 参照 ガイド - レンダー関数 - コンポーネント

resolveDirective()

登録されたディレクティブを名前によって手動で解決します。

  • ts
    function resolveDirective(name: string): Directive | undefined
  • 詳細

    注意: ディレクティブを直接インポートできる場合は不要です。

    resolveDirective() は、正しいコンポーネントコンテキストから解決するために setup() または レンダー関数の内部で呼び出す必要があります。

    ディレクティブが見つからない場合、実行時警告が発生し、この関数は undefined を返します。

  • 参照 ガイド - レンダー関数 - カスタムディレクティブ

withDirectives()

vnode にカスタムディレクティブを追加します。

  • ts
    function withDirectives(
      vnode: VNode,
      directives: DirectiveArguments
    ): VNode
    
    // [Directive, value, argument, modifiers]
    type DirectiveArguments = Array<
      | [Directive]
      | [Directive, any]
      | [Directive, any, string]
      | [Directive, any, string, DirectiveModifiers]
    >
  • 詳細

    既存の vnode をカスタムディレクティブでラップします。第 2 引数はカスタムディレクティブの配列です。各カスタムディレクティブは [Directive, value, argument, modifiers] 形式の配列としても表せます。配列の末尾の要素は、必要なければ省略できます。

  • js
    import { h, withDirectives } from 'vue'
    
    // カスタムディレクティブ
    const pin = {
      mounted() {
        /* ... */
      },
      updated() {
        /* ... */
      }
    }
    
    // <div v-pin:top.animate="200"></div>
    const vnode = withDirectives(h('div'), [
      [pin, 200, 'top', { animate: true }]
    ])
  • 参照 ガイド - レンダー関数 - カスタムディレクティブ

withModifiers()

イベントハンドラー関数に、ビルトインの v-on 修飾子を追加します。

  • ts
    function withModifiers(fn: Function, modifiers: string[]): Function
  • js
    import { h, withModifiers } from 'vue'
    
    const vnode = h('button', {
      // v-on:click.stop.prevent と同等
      onClick: withModifiers(() => {
        // ...
      }, ['stop', 'prevent'])
    })
  • 参照 ガイド - レンダー関数 - イベント修飾子

レンダー関数 APIが読み込まれました