编程知识 cdmana.com

Using V-slot slot in vuetify

brief introduction

Vue since 2.6.0 The release began to introduce a new unified syntax for named slots and scoped slots ( namely v-slot Instructions ). It replaces slot and slot-scope These two are currently obsolete but not removed and are still in the document attribute.
in short , The main purpose of the introduction of slot technology is to undertake “ Place holder ”(placeholder) The role of . I believe many friends are familiar with “ Place holder ” The concept , That is, in the construction UI Or to achieve a function without giving a specific implementation scheme, first use a simplest content to replace , And not to compile and so on the process of syntax errors or try to avoid embarrassment . Please refer to the following brief examples provided by the government :

Sometimes a specific backup is set for a slot ( Which is the default ) The content is very useful , It will only be rendered when no content is provided . For example, in a <submit-button> In the component :


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

We might want this <button> In most cases, the text is rendered in “Submit”. In order to “Submit” As back-up content , We can put it in <slot> tag :

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

Now when I use... In a parent component <submit-button> And does not provide any slot content :


<submit-button></submit-button>

Back up content “Submit” Will be rendered :

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

But if we provide content :


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

Then the provided content will be rendered to replace the backup content :

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

A named slot

When providing content to a named slot , We can do it in one <template> Use on element v-slot Instructions , And v-slot The form of the parameter of provides its name :

<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>

After the colon above header、footer Waiting is equivalent to 2.6 After the version of the slot name attribute .

Now? <template> Everything in the element will be passed to the corresponding slot . Anything not wrapped in a belt with v-slot Of <template> The contents in are treated as the contents of the default slot .

However , If you want to be more specific , Still can be in a <template> The contents of the default slot in the package :

<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>

【 Be careful 】 v-slot Can only be added to <template> On ( There is only one exception ), This and what has been abandoned slot attribute Different .

As a rule , please remember :

Everything in the parent template is compiled in the parent scope ; Everything in the sub template is compiled in the sub scope .

Scope slot

Sometimes it's useful to allow slot content to access data only in a subcomponent .

Binding in <slot> Element attribute go by the name of 【 slot prop】. Now in the parent scope , We can use 【 With value v-slot 】 To define the slots we provide prop Name :

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

In this case , We choose Will contain all slots prop The object of is named slotProps, But you can also use any name you like .

Abbreviation syntax for exclusive default slot

In the above case , When only the default slot is provided , The label of the component can be used as the template of the slot . So we can v-slot Use directly on components :


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

It can be simpler . Just as it is assumed that unspecified content corresponds to the default slot , No parameters v-slot Is assumed to correspond to the default slot :

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

Note that the abbreviation syntax for the default slot cannot be mixed with a named slot , Because it causes ambiguities in scope .

As long as there are multiple slots , Please always use the complete base for all slots <template> The grammar of :


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

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

Deconstruct slot Prop

The internal working principle of a scoped slot is to wrap the contents of the slot in a function with a single parameter :

function (slotProps) {
  //  Slot content 
}

It means : v-slot The value of can actually be anything that can be used as an argument in a function definition JavaScript expression . So in a supported environment ( Single file components or modern browsers ), You can also use ES2015 deconstruction To pass in the specific slot prop, as follows :

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

This makes the template simpler , Especially in this slot there are many prop When . It also turns on prop rename And other possibilities , For example user Rename it to person:

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

You can even define fallback content , For slots prop yes undefined The circumstances of :

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

slot prop Allows us to convert slots to reusable templates , These templates can be based on input prop Render different content . This is most useful when designing reusable components that encapsulate data logic while allowing parent components to customize part of the layout .

What's next , We combine Vuetify UI Common components of the library v-menu To explore how to use in Vuetify Use in the environment v-slot.

Vuetify Use in v-slot slot

Please look at the code. ( A more complicated example , For basic examples, see the following two ):

<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>

There is no specific explanation , Let's start with a question and answer explanation on Manon island , Even though it's English , But there's no problem for you to understand , So there is no translation here :

problem :

Looking at the Vuetify example code for v-toolbar, what is the purpose of v-slot:activator="{ on }"? For example:

<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>

answer

You're likely referring to this example:


<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>

The following line declares a scoped slot named activator, and it is provided a scope object (from VMenu), which contains a property named on:

&lt;template v-slot:activator="{ on }"&gt;
This uses destructuring syntax on the scope object, which IE does not support.

For IE, you'd have to dereference on from the scope object itself:


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

But the ideal solution IMO is to use a Vue CLI generated project, which includes a Babel preset (@vue/babel-preset-app) to automatically include the transforms/polyfills needed for the target browsers. In this case, babel-plugin-transform-es2015-destructuring would be automatically applied during the build.

Details on the activator slot
VMenu allows users to specify a slotted template named activator, containing component(s) that activate/open the menu upon certain events (e.g., click). VMenu provides listeners for those events via an object, passed to the activator slot:

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

The slot content can access VMenu's event listeners like this:


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

For improved readability, the scoped data can also be destructured in the template:


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

The listeners from the scope object are passed to the <button> with v-on's object syntax, which binds one or more event/listener pairs to the element. For this value of on:

{
click: activatorClickHandler // activatorClickHandler is an internal VMenu mixin
}
...the button's click handler is bound to a VMenu method.


Sum up ,Vuetify Several common components in (v-menu、v-tooltip and v-dialog) Use in v-slot Based on Vue Named scope slot technology in , And used ES2015( namely ES6) The grammatical “ destructor ”(destructing).

With v-menu A typical application is , It passes its own set of events and properties to <template> Internal sub components , And pass as needed v-bind and v-on Syntax maps the specific attributes and events of a child component to the corresponding property set and event set of the outer parent component .

v-slot combination v-tooltip Application

    <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-slot combination v-dialog Application

<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>

Important reference

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


版权声明
本文为[1wo6kipk]所创,转载请带上原文链接,感谢

Scroll to Top