# カスタム要素の相互運用性
breaking

# 概要

  • 破壊的変更: タグをカスタム要素として扱うかのチェックは、テンプレートのコンパイル中に実行されるようになりました。そのためランタイム設定ではなくコンパイラオプションで設定する必要があります。
  • 破壊的変更: 特別な is 属性の使用は予約済みの <component> タグのみに制限されます。
  • 新規: ネイティブ HTML のパース制限を回避するためにネイティブ要素で is が使用されていた 2.x のユースケースをサポートするため、値の前に vue: を付けて、Vue コンポーネントとして解決します。

# 自主的なカスタム要素

Vue の外部で定義されたカスタム要素を追加したい場合(例えば Web Components API の使用)、Vue にカスタム要素として扱うように「指示」する必要があります。以下のテンプレートを例にしてみましょう。

<plastic-button></plastic-button>
1

# 2.x での構文

Vue 2.x では、カスタム要素としてタグを設定するには Vue.config.ignoredElements を使用していました。

// 以下で Vue は Vue の外部で定義されたカスタム要素を無視するようになります
// (例: Components APIの使用)

Vue.config.ignoredElements = ['plastic-button']
1
2
3
4

# 3.x での構文

Vue 3.0 では、このチェックはテンプレートのコンパイル時に実行されます。 コンパイラに <plastic-button> をカスタム要素として扱うように指示するには、以下のようにします。

  • ビルドステップを使用する場合: Vue テンプレートコンパイラに isCustomElement オプションを設定します。vue-loader を使用している場合は、vue-loadercompilerOptions オプションを介して設定する必要があります。

    // webpackの設定
    rules: [
      {
        test: /\.vue$/,
        use: 'vue-loader',
        options: {
          compilerOptions: {
            isCustomElement: tag => tag === 'plastic-button'
          }
        }
      }
      // ...
    ]
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
  • 直接テンプレートをコンパイルする場合は、app.config.isCustomElement で設定します。

    const app = Vue.createApp({})
    app.config.isCustomElement = tag => tag === 'plastic-button'
    
    1
    2

    ランタイム設定はランタイムテンプレートのコンパイルにしか影響しないことに注意してください - コンパイル済みのテンプレートには影響しません。

# カスタマイズされたビルトイン要素

カスタム要素の仕様では、ビルトイン要素に is 属性を追加するとこで、カスタム要素をカスタマイズされたビルトイン要素 (opens new window)として利用する方法を提供しています。

<button is="plastic-button">Click Me!</button>
1

Vue では、ブラウザで普遍的に利用できるようになる前のネイティブ属性の動作をシミュレートするために、特別な属性 is を使用していました。しかし、2.x では、plastic-button という名前の Vue コンポーネントをレンダリングしていると解釈されていました。これにより、上記のカスタマイズされたビルトイン要素のネイティブな使用がブロックされます。

3.0 では、Vue の is 属性の特別な扱いを <component> タグのみに制限しています。

  • 予約済みの <component> タグで使用された場合、2.x と全く同じ動作をします。

  • 通常のコンポーネントに使用すると、通常の属性のように動作します。

    <foo is="bar" />
    
    1
  • 2.x の動作: bar コンポーネントをレンダリングします。

  • 3.x の動作: foo コンポーネントをレンダリングし、is 属性を渡します。

  • 通常の要素で使用される場合、is 属性として createElement の呼び出しに渡され、ネイティブ属性としてもレンダリングされます。これはカスタマイズされたビルトイン要素の使用をサポートします。

    <button is="plastic-button">Click Me!</button>
    
    1
  • 2.x の動作: plastic-button コンポーネントをレンダリングします。

  • 3.x の動作: ネイティブなボタンをレンダリングします。

    document.createElement('button', { is: 'plastic-button' })
    
    1

移行ビルドのフラグ: COMPILER_IS_ON_ELEMENT

# vue: プレフィックスは DOM 内テンプレートパースのための回避策

注: このセクションは、Vue テンプレートがページの HTML に直接記述されている場合にのみ影響します。 DOM 内テンプレートを使用している場合、テンプレートはネイティブ HTML パースルールに従います。HTML 要素の中には、<ul>, <ol>, <table>, <select> のように、その中に表示できる要素に制限があり、また、<li>, <tr>, <option> のように、特定の他の要素の中にしか表示できない要素もあります。

# 2.x での構文

Vue 2 では、ネイティブタグに is 属性を使用してこれらの制限を回避することを推奨しています。

<table>
  <tr is="blog-post-row"></tr>
</table>
1
2
3

# 3.x での構文

is の動作変更に伴い、要素を Vue コンポーネントとして解決するには vue: プレフィックスが必要になりました。

<table>
  <tr is="vue:blog-post-row"></tr>
</table>
1
2
3

# 移行の戦略

  • config.ignorededElementsvue-loadercompilerOptions(ビルドステップ)または app.config.isCustomElement(直接テンプレートコンパイル)のいずれかで置き換えます。

  • <component> 以外のタグで is を使用しているものはすべて <component is="...">(SFC テンプレートの場合)または vue: プレフィックス(DOM 内テンプレートの場合)に変更します。