Vuetifyでvスロットを使用する

前書き

Vueは、バージョン2.6.0以降、名前付きスロットとスコープ付きスロットに新しい統合構文(つまり、v-slot命令)を導入しました。これは、現在廃止されているが削除されておらず、まだドキュメントに残っている2つの属性であるslotとslot-scopeを置き換えます。
要するに、スロット技術の導入の主な目的は、「プレースホルダー」の役割を引き受けることです。多くの友人は「プレースホルダー」の概念に精通していると思います。つまり、UIを構築したり、特定の実装計画を指定せずに特定の機能を実装したりする場合は、コンパイルプロセスでの文法エラーを回避するために、最初に最も単純なコンテンツを使用して置き換えます。または、恥ずかしさを避けてください。職員が提供する以下の簡単な例を参照してください。

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

提供されたコンテンツは、バックアップコンテンツを置き換えるためにレンダリングされます。

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

名前付きスロット

名前付きスロットにコンテンツを提供する場合、<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>

上記のコロンの後のヘッダーとフッターは、バージョン2.6以降のスロットのname属性と同等です。

これで、<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>

[注] v-slotは<template>にのみ追加できます(例外は1つだけです)。これは、非推奨のslot属性とは異なります。

原則として、次の点に注意してください。

親テンプレートのすべてのコンテンツは親スコープでコンパイルされます。子テンプレートのすべてのコンテンツは子スコープでコンパイルされます。

スコープスロット

スロットのコンテンツがサブコンポーネントでのみ使用可能なデータにアクセスできるようにすると便利な場合があります。

<slot>要素にバインドされた属性は[slotprop]と呼ばれます。これで、親スコープで、[v-slot with value]を使用して、提供するスロットプロップの名前を定義できます。

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

この例では、すべてのスロット小道具slotPropsを含むオブジェクトに名前を付けることを選択しましたが、任意の名前を使用できます。

排他的デフォルトスロットの省略された構文

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


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

この書き方はもっと簡単です。指定されていないコンテンツがデフォルトのスロットに対応すると想定するのと同じように、パラメータのないvスロットはデフォルトのスロットに対応すると想定されます。

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

デフォルトスロットの省略された構文は、スコープがあいまいになるため、名前付きスロットと混合できないことに注意してください。

複数のスロットが表示される場合は常に、すべてのスロットに完全な<template>ベースの構文を使用してください。


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

  <template v-slot:other="otherSlotProps">
    ...
  </template>
</current-user>

スロットプロップを分解する

スコープスロットの内部動作原理は、スロットの内容を単一のパラメーターを持つ関数でラップすることです。

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

つまり、v-slotの値は、実際には、関数定義のパラメーターとして使用できる任意のJavaScript式にすることができます。したがって、サポートされている環境(単一ファイルコンポーネントまたは最新のブラウザ)では、次のように、ES2015デストラクチャリングを使用して特定のスロット小道具を渡すこともできます。

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

これにより、特にスロットが複数の小道具を提供する場合に、テンプレートをより簡潔にすることができます。また、ユーザーから個人への名前変更など、小道具の名前変更などの他の可能性も開きます

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

スロットプロップが未定義の場合に使用されるフォールバックコンテンツを定義することもできます。

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

スロットプロップを使用すると、スロットを再利用可能なテンプレートに変換できます。これにより、入力プロップに基づいてさまざまなコンテンツをレンダリングできます。これは、親コンポーネントが部分的なレイアウトをカスタマイズできるようにしながら、データロジックをカプセル化する再利用可能なコンポーネントを設計する場合に最も役立ちます。

次のコンテンツでは、VuetifyUIライブラリの共通コンポーネントvメニューの使用と組み合わせてVuetify環境でvスロットを使用する方法について説明します。

Vuetifyでvスロットを使用する

コードを見てください(より複雑な例については、基本的な例については次の2つを参照してください)。

<template>
  <div class="text-center">
    <v-menu>
      <template v-slot:activator="{ on: menu, attrs }">
        <v-tooltip bottom>
          <template v-slot:activator="{ on: tooltip }">
            <v-btn
              color="primary"
              dark
              v-bind="attrs"
              v-on="{ ...tooltip, ...menu }"
            >
              Dropdown w/ Tooltip
            </v-btn>
          </template>
          <span>Im A ToolTip</span>
        </v-tooltip>
      </template>
      <v-list>
        <v-list-item
          v-for="(item, index) in items"
          :key="index"
        >
          <v-list-item-title>{{ item.title }}</v-list-item-title>
        </v-list-item>
      </v-list>
    </v-menu>
  </div>
</template>

ここでは具体的な説明はしませんが、まずコデノン島のQ&Aの説明を見てみましょう。英語ですが、理解しても問題ないので、ここでは翻訳しません。

問題:

v-toolbarのVuetifyサンプルコードを見ると、v-slot:activator = "{on}"の目的は何ですか?例えば:

<template v-slot:activator="{ on }">
  <v-toolbar-title v-on="on">
    <span>All</span>
    <v-icon dark>arrow_drop_down</v-icon>
  </v-toolbar-title>
</template>

応答

あなたはおそらくこの例を参照しています:


<v-toolbar color="grey darken-1" dark>
  <v-menu :nudge-width="100">
    <template v-slot:activator="{ on }">
      <v-toolbar-title v-on="on">
        <span>All</span>
        <v-icon dark>arrow_drop_down</v-icon>
      </v-toolbar-title>
    </template>

    ...
  </v-menu>
</v-toolbar>

次の行は、activatorという名前のスコープスロットを宣言しており、次の名前のプロパティを含むスコープオブジェクト(VMenuから)が提供されています。

&lt;template v-slot:activator="{ on }"&gt;
これは、IEがサポートしていないスコープオブジェクトの非構造化構文を使用します。

IEの場合、スコープオブジェクト自体から逆参照する必要があります。


<template v-slot:activator="scope">
  <v-toolbar-title v-on="scope.on">

ただし、IMOの理想的なソリューションは、Vue CLIで生成されたプロジェクトを使用することです。このプロジェクトにはBabelプリセット(@ vue / babel-preset-app)が含まれており、ターゲットブラウザーに必要な変換/ポリフィルが自動的に含まれます。この場合、babel-plugin-transform-es2015-destructuringはビルド中に自動的に適用されます。

アクティベータースロットの詳細
VMenuを使用すると、ユーザーは、特定のイベント(クリックなど)でメニューをアクティブ化/開くコンポーネントを含む、アクティベーターという名前のスロット付きテンプレートを指定できます。VMenuは、アクティベータースロットに渡されるオブジェクトを介して、これらのイベントのリスナーを提供します。

<v-menu>
  <template v-slot:activator="scopeDataFromVMenu">
    <!-- slot content goes here -->
  </template>
</v-menu>

スロットコンテンツは、次のようにVMenuのイベントリスナーにアクセスできます。


<v-menu>
  <template v-slot:activator="scopeDataFromVMenu">
    <button v-on="scopeDataFromVMenu.on">Click</button>
  </template>
</v-menu>

読みやすさを向上させるために、スコープデータをテンプレートで非構造化することもできます。


<!-- equivalent to above -->
<v-menu>
  <template v-slot:activator="{ on }">
    <button v-on="on">Click</button>
  </template>
</v-menu>

スコープオブジェクトのリスナーは、v-onのオブジェクト構文を使用して<button>に渡されます。これにより、1つ以上のイベント/リスナーのペアが要素にバインドされます。onのこの値の場合:

{
クリック:activatorClickHandler // activatorClickHandlerは内部VMenuミックスインです
}
...ボタンのクリックハンドラーはVMenuメソッドにバインドされています。

要約すると、Vuetifyで一般的に使用されるいくつかのコンポーネント(v-menu、v-tooltip、v-dialog)でv-slotを使用する基本は、Vueの名前付きスコープスロットテクノロジーに基づいており、ES2015(つまり、ES6)構文を使用します。 (破壊)の「破壊」。

v-menuの典型的なアプリケーションを例にとると、独自のイベントセットと属性セットを名前付きスコープスロットを介して<template>の内部サブコンポーネントに渡し、v-bindおよびv-on構文を使用して、必要に応じて特定のサブコンポーネントを決定します。属性とイベントは、外部の親コンポーネントに対応する属性セットとイベントセットにマップされます。

v-tooltipと組み合わせたv-slotの適用

    <v-tooltip bottom>
      <template v-slot:activator="{ on, attrs }">
        <v-btn
          color="primary"
          dark
          v-bind="attrs"
          v-on="on"
        >
          Button
        </v-btn>
      </template>
      <span>Tooltip</span>
    </v-tooltip>

v-dialogと組み合わせたv-slotの適用

<v-dialog
      v-model="dialog"
      width="500"
    >
      <template v-slot:activator="{ on, attrs }">
        <v-btn
          color="red lighten-2"
          dark
          v-bind="attrs"
          v-on="on"
        >
          Click Me
        </v-btn>
      </template>

      <v-card>
        <v-card-title class="headline grey lighten-2">
          Privacy Policy
        </v-card-title>

        <v-card-text>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
        </v-card-text>

        <v-divider></v-divider>

        <v-card-actions>
          <v-spacer></v-spacer>
          <v-btn
            color="primary"
            text
            @click="dialog = false"
          >
            I accept
          </v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

重要な参考資料

https://blog.csdn.net/weixin_44710964/article/details/107428727
https://cn.vuejs.org/v2/guide/components-slots.html
https://vuetifyjs.com/en/components/menus/ #activator-and-tooltip
https://www.manongdao.com/article-1850182.html

おすすめ

転載: blog.51cto.com/zhuxianzhong/2548252