Vue.jsテンプレートは非常に強力で、アプリで必要となるほとんどすべてのことを実行できます。 ただし、いくつかのユースケースがあり、多くの場合、レンダリング関数によってより適切に提供される入力値またはスロット値に基づく動的コンポーネントの作成が含まれます。

Reactの世界から来た人は、おそらくレンダリング機能に非常に精通しています。 Reactコンポーネントは、通常JSXを介してそれらを使用して構築されます。 また、Vueレンダリング関数はJSXで記述することもできますが、Vueのコンポーネントシステムの基盤をより簡単に理解できるように、生のJSを使用します。

Vue.jsのテンプレートは、実際にはビルド時に関数をレンダリングするためにコンパイルされることに注意してください。 テンプレートは、レンダリング関数に加えて、便利で使い慣れた構文糖衣構文を提供するだけです。 より強力ですが、レンダリング機能は読みやすさの部門で苦しむことがよくあります。

コンポーネントの作成

レンダリング機能を備えたコンポーネントには、テンプレートタグまたはプロパティがありません。 代わりに、 createElement(renderElement:String | Component、definition:Object、children:String | Array)引数(通常は h [ X209X]、何らかの理由でJSXを非難し、その関数で作成された要素を返します。 他のすべては同じままです。

ExampleComponent.vue
export default {
  data() {
    return {
      isRed: true
    }
  },

  /*
   * Same as
   * <template>
   *   <div :class="{'is-red': isRed}">
   *     <p>Example Text</p>
   *   </div>
   * </template>
   */
  render(h) {
    return h('div', {
      'class': {
        'is-red': this.isRed
      }
    }, [
      h('p', 'Example Text')
    ])
  }
}

短縮ディレクティブの置き換え

Vueテンプレートには、基本的なロジックとバインディング機能をテンプレートに追加するためのさまざまな便利な機能が付属しています。 レンダリング関数はこれらにアクセスできません。 代わりに、プレーンなJavascriptで実装する必要があります。これは、ほとんどのディレクティブで、かなり単純です。

v-if

これは簡単です。 v-if を使用する代わりに、createElement呼び出しの周りに通常のJavascriptif(expr)ステートメントを使用してください。

v-for

v-for は、多くのJavascript反復法、 for、for-of、Array.map、Array.filterなどのいずれかを使用して実装できます。 これらを非常に興味深い方法で組み合わせて、計算されたプロパティを必要とせずにフィルタリングまたは状態スライスを実装できます。

たとえば、置き換えることができます

<template>
  <ul>
    <li v-for="pea of pod">
      {{pea.name}}
    </li>
  </ul>
</template>

render(h) {
  return h('ul', this.pod.map(pea => h('li', pea.name)));
}

vモデル

v-model は、 value へのバインディングプロパティの省略形であり、inputイベントが発生するたびにデータプロパティを設定することを覚えておいてください。 。 残念ながら、レンダリング関数のそのような省略形はありません。 以下に示すように、自分で実装する必要があります。

render(h) {
  return h('input', {
    domProps: {
      value: this.myBoundProperty
    },
    on: {
      input: e => {
        this.myBoundProperty = e.target.value
      }
    }
  })
}

これは次と同等です:

<template>
  <input :value="myBoundProperty" @input="myBoundProperty = $event.target.value"/>
</template>

また

<template>
  <input v-model="myBoundProperty"/>
</template>

v-bind

属性とプロパティのバインディングは、 arttrs props domProps valueなど)のように要素定義に配置されます。 innerHTML )。

render(h) {
  return h('div', {
    attrs: {
      // <div :id="myCustomId">
      id: this.myCustomId
    },

    props: {
      // <div :someProp="someonePutSomethingHere">
      someProp: this.someonePutSomethingHere
    },

    domProps: {
       // <div :value="somethingElse">
      value: this.somethingElse
    }
  });
}

ちなみに、クラスとスタイルのバインディングは、 attrs、props、またはdomProps としてではなく、定義のルートで直接処理されます。

render(h) {
  return h('div', {
    // "class" is a reserved keyword in JS, so you have to quote it.
    'class': {
      myClass: true,
      theirClass: false
    },

    style: {
      backgroundColor: 'green'
    }
  });
}

v-on

イベントハンドラーは、 on (または nativeOn で、コンポーネントの v-on.nativeと同じ効果があります)の要素定義に直接追加されます。 )。

render(h) {
  return h('div', {
    on: {
      click(e) {
        console.log('I got clickeded!')
      }
    }
  });
}

修飾子はハンドラー内に実装できます。

  • .stop -> e.stopPropagation()
  • .prevent -> e.preventDefault()
  • .self -> if(e.target!== e.currentTarget)return

キーボード修飾子

  • 。[TARGET_KEY_CODE]-> if(event.keyCode!== TARGET_KEY_CODE)return
  • 。[MODIFIER]-> if(!event.MODIFIERKey)return

特別なプロパティ

Slots には、this。$slotsを介してcreateElement()ノードの配列としてアクセスできます。

スコープスロットは、 createElement()ノードの配列を返す関数としてthis。$scopedSlots [scope](props:object)に格納されます。

レンダリング機能によって与えられる新しい無制限のパワーをお楽しみください! 賢く使うように注意してください。