Slot is commonly used in vue3

Let's get to know the slot first

In development, we often encapsulate reusable components:

  1. Previously, we'll pass some data to the component through props so that it can be displayed.
  2. However, in order to make this component more versatile, we cannot restrict the contents of the component to fixed div, span, and so on.
  3. We should allow users to decide what content and elements to store in an area.

How to use slot?

  1. In fact, the process of using the slot is to extract common features and reserve different ones.
  2. We will still encapsulate the common elements and contents within the components.
  3. At the same time, slot s are used as placeholders for different elements, allowing the outside to decide what elements to display.
  4. In an encapsulated component, a slot can be opened for the encapsulated component using a special element.
  5. What the slot inserts depends on how the parent component is used;

Basic use of slots


App.vue

<template>
  <div>
    <my-slot-cpn>
      <button>I am a button</button>
    </my-slot-cpn>
    <my-slot-cpn>
      <my-input-cpn />
    </my-slot-cpn>
    <h2>I am not a component of the slot</h2>
    <my-slot-cpn>
      <h4>Lots of stuff in the slot</h4>
      <i>Do you trust me?</i>
      <del>Come on.</del>
    </my-slot-cpn>
    <my-slot-cpn></my-slot-cpn>
  </div>
</template>

<script>
import MySlotCpn from "./MySlotCpn.vue";
import MyInputCpn from "./MyInputCpn.vue";
export default {
  name: "App",
  components: { MySlotCpn, MyInputCpn },
  methods: {},
};
</script>

<style scoped>
</style>

MySlotCpn.vue

<template>
  <div>
    <h3>Start of component</h3>
    <slot>
      <i>I am a slot, no information is filled in, I am the default</i>
    </slot>
    <h3>End of component</h3>
  </div>
</template>

<script>
export default {};
</script>

<style lang="scss" scoped>
</style>

MyInputCpn.vue

<template>
  <div>
    <input type="text" placeholder="I'm an input box" />
  </div>
</template>

<script>
export default {};
</script>

<style lang="scss" scoped>
</style>

Use of named slots - dynamic slot names

  1. A named slot, as its name implies, gives the slot a name, and the element has a special attribute: name.
  2. A slot without a name, with the implied name default;

We can dynamically bind a name via v-slot:[dynamicSlotName];
Abbreviations for named slots:
Like v-on and v-bind, v-slot has abbreviations;
That is, replace everything before the parameter (v-slot:) with the character #;

<template>
  <div>
    <nar-bar :name="name">
      <template v-slot:left> I am the slot on the left </template>
      <template v-slot:center>I am the middle slot</template>
      <template v-slot:right>I am the right slot</template>
      <template #[name]>I am a grammar sugar and dynamic slot </template>
    </nar-bar>
  </div>
</template>

<script>
import NarBar from "./NarBar.vue";

export default {
  name: "App",
  data() {
    return {
      name: "lisi",
    };
  },
  components: {
    NarBar,
  },
};
</script>

<template>
  <div>
    <div class="nav-bar">
      <div class="left"><slot name="left"></slot></div>
      <div class="center"><slot name="center"></slot></div>
      <div class="right"><slot name="right"></slot></div>
      <div class="name"><slot :name="name"></slot></div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    name: String,
  },
};
</script>

Render Scope

There is a concept of rendering scope in Vue:

  1. All content in the parent template is compiled in the parent scope;
  2. Everything in a sub-template is compiled in a sub-scope;

List

Understanding Scope Slot

But sometimes it is very important that we want the slot to have access to the contents of the subcomponents:

  1. When a component is used to render an array element, we use a slot, and we want the slot to display nothing for each item.
  2. This Vue provides us with a scoped slot;

Use steps

ShowNames.vue

<template>
  <div>
    <template v-for="(item, index) in names" :key="item">
      <slot :item="item" :index="index"></slot>
      <slot name="lisi"></slot>
    </template>
  </div>
</template>

<script>
  export default {
    props: {
      names: {
        type: Array,
        default: () => []
      }
    }
  }
</script>

<style scoped>

</style>

App.vue

<template>
  <div>
    <nar-bar :name="name">
      <template v-slot:left> I am the slot on the left </template>
      <template v-slot:center>I am the middle slot</template>
      <template v-slot:right>I am the right slot</template>
      <template #[name]>I am a grammar sugar and dynamic slot </template>
    </nar-bar>
    <hr />
    <show-names :names="names">
      <template v-slot="names">
        <p>{{ names.item }}-{{ names.index }}</p>
      </template>
    </show-names>
    <hr />
    // If we have default and named slots, then follow the full template
    <show-names :names="names">
      <template v-slot="slotProps">
        <span>{{ slotProps.item }}---{{ slotProps.index }}</span>
      </template>
    </show-names>
    <hr />
    // If only the default slot is in our slot, the label of the component can be used as a template for the slot, so that we can use v-slot directly on the component
    <show-names :names="names" v-slot="slotProps">
      <button>{{ slotProps.item }}-{{ slotProps.index }}</button>
    </show-names>
    <hr />
    <show-names :names="names">
      <template v-slot="slotProps">
        <button>{{ slotProps.item }}-{{ slotProps.index }}</button>
      </template>
      //If our slot is default, v-slot:default="slotProps" can be abbreviated as V slot="slotProps" when used:
      <template v-slot:lisi>
        <h2>I am name Insertion of</h2>
      </template>
    </show-names>
  </div>
</template>

<script>
import NarBar from "./NarBar.vue";
import ShowNames from "./ShowNames.vue";

export default {
  name: "App",
  data() {
    return {
      names: ["Zhang San", "Li Si", "King Five", "Zhao Six", "Sun Qi"],
    };
  },
  components: {
    NarBar,
    ShowNames,
  },
};
</script>

Keywords: Javascript html5 Vue.js

Added by janhouse00 on Wed, 06 Oct 2021 19:41:44 +0300