スロット


このページは、コンポーネントの基本を読んでいることを前提としています。コンポーネントについてまだよく知らない場合は、最初に読むことをお勧めします。

2.6.0 では、名前付きスロットとスコープ付きスロットの新しい統合構文 (v-slot ディレクティブ) を導入しました。これは、現在非推奨ですが削除されておらず、まだ ドキュメント に記載されている slotslot-scope を置き換えます。新しい構文の起源は、この #RFC にあります。


#目次

  • ##スロットの内容

  • #コンパイル スコープ
  • バックアップ コンテンツ
  • #名前付きスロット
  • スコープ スロット
  • 排他的なデフォルト スロットの省略構文
    • #分解されたスロット プロップ

    • # #動的スロット名
  • #名前付きスロットの略語

  • その他の例

  • 非推奨の構文

  • スロット属性を持つ名前付きスロット

    • スロット スコープ属性を持つスコープ スロット

# #Slot content


Vue は、一連のコンテンツ配布 API を実装しています。このセットの API の設計は、

Web コンポーネントのドラフト仕様 からインスピレーションを受けており、以下を使用します。 <slot> 要素は、分散コンテンツを運ぶ出口として使用されます。

これにより、次のようにコンポーネントを合成できます:
<navigation-link url="/profile">
  Your Profile
</navigation-link>

次に、<navigation-link> のテンプレートに次のように記述します:

<a
  v-bind:href="url"
  class="nav-link"
>
  <slot></slot>
</a>
コンポーネントがレンダリングされると、

<slot></slot>

は「Your Profile」に置き換えられます。スロットには、HTML:

<navigation-link url="/profile">
  <!-- 添加一个 Font Awesome 图标 -->
  <span class="fa fa-user"></span>
  Your Profile
</navigation-link>

または他のコンポーネント: を含む任意のテンプレート コードを含めることができます。

<navigation-link url="/profile">
  <!-- 添加一个图标的组件 -->
  <font-awesome-icon name="user"></font-awesome-icon>
  Your Profile
</navigation-link>

<navigation-link><slot> 要素が含まれていない場合、コンポーネントの開始タグと終了タグの間のコンテンツはすべて破棄されます。


#コンパイルスコープ


スロット内のデータを使用したい場合など:

<navigation-link url="/profile">
  Logged in as {{ user.name }}
</navigation-link>

このスロットは、テンプレート内の他の場所と同じインスタンス プロパティ (つまり、同じ「スコープ」) にアクセスできますが、<navigation-link> のスコープにはアクセスできません。たとえば、URL にアクセスできません:

<navigation-link url="/profile">
  Clicking here will send you to: {{ url }}
  <!--
  这里的 `url` 会是 undefined,因为 "/profile" 是
  _传递给_ <navigation-link> 的而不是
  在 <navigation-link> 组件*内部*定义的。
  -->
</navigation-link>

原則として、次のことを覚えておいてください:

親テンプレート内のすべてのものは親スコープ内にあります。子テンプレートは子スコープでコンパイルされます。


#フォールバック コンテンツ

スロットに設定される場合がありますコンテンツが提供されていない場合にのみレンダリングされる特定のフォールバック (つまり、デフォルト) コンテンツを用意すると便利です。たとえば、
<submit-button>

コンポーネントでは:

<button type="submit">
  <slot></slot>
</button>
ほとんどの場合、この

<button>

でテキスト「Submit」をレンダリングすることができます。 」。 「Submit」をフォールバックとして使用するには、それを <slot> タグ内に置くことができます:

<button type="submit">
  <slot>Submit</slot>
</button>
親コンポーネントの submit-button> で

< を使用すると、

スロット コンテンツが提供されていない場合:

<submit-button></submit-button>
フォールバック コンテンツ "Submit" がレンダリングされます:

<button type="submit">
  Submit
</button>

しかし、コンテンツを提供した場合:

<submit-button>
  Save
</submit-button>

Then提供されたコンテンツは、フォールバック コンテンツの代わりにレンダリングされます:

<button type="submit">
  Save
</button>


##名前付きスロット

#2.6.0から更新されました。
slot
機能を使用するための非推奨の構文は

here です。 複数のスロットが必要な場合があります。たとえば、次のテンプレートを持つ

<base-layout>
コンポーネントの場合:

<div class="container">
  <header>
    <!-- 我们希望把页头放这里 -->
  </header>
  <main>
    <!-- 我们希望把主要内容放这里 -->
  </main>
  <footer>
    <!-- 我们希望把页脚放这里 -->
  </footer>
</div>
このような場合、<slot>

要素には特別な属性があります。 : ###名前###。この機能は、追加のスロットを定義するために使用できます。

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>
A <slot> name

のないアウトレットには、暗黙的な名前 "default" が付けられます。

名前付きスロットにコンテンツを提供する場合、<template> 要素で v-slot

ディレクティブを使用し、

v で終わることができます。 -slot パラメーターは、その名前を次の形式で指定します。

<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>
  <p>A paragraph for the main content.</p>
  <p>And another one.</p>
  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>
これで、<template> 要素内のすべてのコンテンツが、対応するスロットに渡されます。 v-slot

を使用して

<template> でラップされていないものは、デフォルトのスロットの内容として扱われます。

ただし、より明示的にしたい場合は、デフォルト スロットの内容を <template> でラップすることもできます:

<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>
  <template v-slot:default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>
  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

どちらの方法でもレンダリングされます:

<div class="container">
  <header>
    <h1>Here might be a page title</h1>
  </header>
  <main>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </main>
  <footer>
    <p>Here's some contact info</p>
  </footer>
</div>

注: v-slot<template> にのみ追加できます (1 つの例外 のみ)。これは非推奨と同じですスロットの機能 は異なります。


#スコープ スロット


##2.6.0 更新以降で利用可能。
slot-scope

機能を使用するための非推奨の構文は here です。

子コンポーネントでのみ利用可能なデータへのスロット コンテンツ アクセスを許可すると便利な場合があります。たとえば、次のテンプレートを持つ
<current-user>

コンポーネントを想像してください:

<span>
  <slot>{{ user.lastName }}</slot>
</span>
そのフォールバック コンテンツには、通常のユーザーの姓ではなく、ユーザーの名が表示されるようにしたいと考えています。次のように:

<current-user>
  {{ user.firstName }}
</current-user>

ただし、

<current-user>

コンポーネントのみが user にアクセスでき、提供されるコンテンツは次のとおりであるため、上記のコードは正しく機能しません。 in 親によってレンダリングされます。 親のスロット コンテンツで

user

を使用できるようにするには、user<slot> 要素の属性にバインドします。

<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>

<slot>

要素にバインドされたプロパティは、slot prop と呼ばれます。これで、親スコープで、提供するスロット プロパティの名前を定義する値を v-slot に与えることができます:

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>
この例では、すべてのスロット プロパティ オブジェクトを含めることを選択します。

slotProps

という名前が付けられていますが、任意の名前を使用できます。


専用デフォルトスロットの省略構文 上記の場合、コンテンツが提供される場合のみデフォルトのスロットでは、コンポーネントのラベルをスロットのテンプレートとして使用できます。このようにして、コンポーネント上で

v-slot

を直接使用できます。

<current-user v-slot:default="slotProps">
  {{ slotProps.user.firstName }}
</current-user>
この書き方の方が簡単です。未指定のコンテンツがデフォルトのスロットに対応すると想定されるのと同様に、引数のない

v-slot

はデフォルトのスロットに対応すると想定されます:

<current-user v-slot="slotProps">
  {{ slotProps.user.firstName }}
</current-user>
デフォルト スロットの省略された構文に注意してください

スコープが曖昧になるため、名前付きスロットと

を混合することはできません:

<!-- 无效,会导致警告 -->
<current-user v-slot="slotProps">
  {{ slotProps.user.firstName }}
  <template v-slot:other="otherSlotProps">
    slotProps is NOT available here
  </template>
</current-user>
複数のスロットが存在する場合は、常に完全な

<template> ;

構文を使用してください:

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
  <template v-slot:other="otherSlotProps">
    ...
  </template>
</current-user>


スロット Propスコープ スロットの構造内部の仕組みは、スロットの内容をラップすることです。単一の引数を取る関数:

function (slotProps) {
  // 插槽内容
}

これは、v-slot の値は、実際には関数定義のパラメーターとして渡すことができる任意の JavaScript 式にすることができることを意味します。したがって、サポートされている環境 (単一ファイル コンポーネント または モダン ブラウザ) では、ES2015 Destructuring を使用して特定のスロット プロパティは次のとおりです。

<current-user v-slot="{ user }">
  {{ user.firstName }}
</current-user>

これにより、特にスロットが複数のプロパティを提供する場合、テンプレートをより簡潔にすることができます。また、userperson に名前変更するなど、プロパティの名前変更の他の可能性も広がります。

<current-user v-slot="{ user: person }">
  {{ person.firstName }}
</current-user>

スロット プロパティのフォールバック コンテンツを定義することもできます。これは未定義です:

<current-user v-slot="{ user = { firstName: 'Guest' } }">
  {{ user.firstName }}
</current-user>


動的スロット名


2.6 .0 追加

動的コマンド パラメータ は、v-slot で動的スロット名を定義するために使用することもできます:

<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>
</base-layout>


名前付きスロットの略称


##2.6.0 New

Like

v-on v-bindv-slot にも省略形があります。つまり、パラメーター (v -slot:) より前のすべての内容が、文字 #。たとえば、v-slot:header#header:

<base-layout>
  <template #header>
    <h1>Here might be a page title</h1>
  </template>
  <p>A paragraph for the main content.</p>
  <p>And another one.</p>
  <template #footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

のように書き換えることができます。ただし、他のディレクティブと同様、この省略形はパラメーターがある場合にのみ使用されます。 。これは、次の構文が無効であることを意味します:

<!-- 这样会触发一个警告 -->
<current-user #="{ user }">
  {{ user.firstName }}
</current-user>

省略形を使用する場合は、必ず明示的なスロット名に置き換える必要があります:

<current-user #default="{ user }">
  {{ user.firstName }}
</current-user>


##その他の例


スロット プロパティを使用すると、スロットを、入力プロパティのさまざまなコンテンツに基づいてレンダリングできる再利用可能なテンプレートに変換できます。

これは、親コンポーネントがレイアウトの一部をカスタマイズできるようにしながら、データ ロジックをカプセル化する再利用可能なコンポーネントを設計する場合に最も役立ちます。 たとえば、

<todo-list>

コンポーネントを実装したいとします。これはリストであり、レイアウトとフィルタリング ロジックが含まれています。

<ul>
  <li
    v-for="todo in filteredTodos"
    v-bind:key="todo.id"
  >
    {{ todo.text }}
  </li>
</ul>
それぞれを追加できます。 todo 親コンポーネントのスロットとして、親コンポーネントを通じて制御し、

todo

をスロット プロパティとしてバインドします:

<ul>
  <li
    v-for="todo in filteredTodos"
    v-bind:key="todo.id"
  >
    <!--
    我们为每个 todo 准备了一个插槽,
    将 `todo` 对象作为一个插槽的 prop 传入。
    -->
    <slot name="todo" v-bind:todo="todo">
      <!-- 后备内容 -->
      {{ todo.text }}
    </slot>
  </li>
</ul>

<todo-list> を使用する場合;

コンポーネントでは、代わりに todo に別の <template> を定義することを選択でき、サブコンポーネントからデータを取得できます:

<todo-list v-bind:todos="todos">
  <template v-slot:todo="{ todo }">
    <span v-if="todo.isComplete">?</span>
    {{ todo.text }}
  </template>
</todo-list>

これはスコープ スロットが役立つ氷山の一角にすぎません。スコープ付きスロットを実際に使用するには、Vue Virtual ScrollerVue PromizedPortal Vue などのライブラリを参照することをお勧めします。


#廃止された構文


v - slot ディレクティブは、slot および slot-scope 機能をより適切にサポートする API 代替手段を提供するために、Vue 2.6.0 で導入されました。 v-slot 詳細については、この RFC を参照してください。 slot および slot-scope 機能は、後続のすべての 2.x バージョンで引き続きサポートされますが、正式に非推奨となっており、Vue 3 には表示されません。


slot 属性を持つ名前付きスロット

2.6.0 以降非推奨になりました。新しい推奨される構文については、

こちらを確認してください。

##<template>
の特別な

slot 属性を使用して、親から名前付きスロットにコンテンツを渡します (ここに # を入力します) ##<base-layout> コンポーネントを例として挙げました):

<base-layout>
  <template slot="header">
    <h1>Here might be a page title</h1>
  </template>
  
  <p>A paragraph for the main content.</p>
  <p>And another one.</p>
  
  <template slot="footer">
    <p>Here's some contact info</p>
  </template>
</base-layout>
または、通常の要素の slot 属性を直接使用します 上記:

<base-layout>
  <h1 slot="header">Here might be a page title</h1>
  
  <p>A paragraph for the main content.</p>
  <p>And another one.</p>
  
  <p slot="footer">Here's some contact info</p>
</base-layout>

実際にはここに名前のないスロットがあり、これは デフォルト スロットで、一致しないコンテンツをすべてキャプチャします。上記 2 つの例の HTML レンダリング結果は次のとおりです。

<div class="container">
  <header>
    <h1>Here might be a page title</h1>
  </header>
  <main>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </main>
  <footer>
    <p>Here's some contact info</p>
  </footer>
</div>


##slot-scope

属性

## を持つスコープ スロット# 2.6.0 以降は非推奨になりました。新しい推奨構文については、ここを確認してください。

<template> の特殊な slot-scope

属性を使用して、スロットに渡されたプロパティを受け取ります (
ここに

言及<slot-example> 例としてのコンポーネント):

<slot-example>
  <template slot="default" slot-scope="slotProps">
    {{ slotProps.msg }}
  </template>
</slot-example>

ここの slot-scope は、受信した prop オブジェクトが <template> スコープ内に slotProps 変数として存在することを宣言します。 slotProps には、JavaScript 関数のパラメーターに名前を付けるのと同じように、任意に名前を付けることができます。

ここでの slot="default" は、暗黙的な記述として無視できます:

<slot-example>
  <template slot-scope="slotProps">
    {{ slotProps.msg }}
  </template>
</slot-example>

slot-scope この機能は、次の目的で直接使用することもできます。非 <template> 要素 (コンポーネントを含む):

<slot-example>
  <span slot-scope="slotProps">
    {{ slotProps.msg }}
  </span>
</slot-example>

slot-scope の値は、パラメータ位置に表示できる任意の有効な JavaScript を受け入れることができます。関数定義式。これは、サポートされている環境 (単一ファイル コンポーネント または 最新ブラウザ) では、次のように式 ## で ES2015 Destructuring# を使用することもできることを意味します。 :

<slot-example>
  <span slot-scope="{ msg }">
    {{ msg }}
  </span>
</slot-example>

ここで説明した <todo-list> を例として使用し、同等の使用として slot-scope を使用します。 のコードは次のとおりです。 :

<todo-list v-bind:todos="todos">
  <template slot="todo" slot-scope="{ todo }">
    <span v-if="todo.isComplete">?</span>
    {{ todo.text }}
  </template>
</todo-list>