vue2 slot: slot, slot-scoped, v-slot

1. Slots in vue

1.1 The problem to be solved by the slot in vue

slot Slot is used in components to distribute content to components. Its content can contain any template code, including HTML. It will solve the following problems:

<template>
  <div>
    <p>buttonTest</p>
    <my-button>
      <!-- How to display the content in the custom label -->
      button
    </my-button>
  </div>
</template>
<script>
import MyButton from "./MyButton.vue";

export default {
  components: {
    "my-button": MyButton,
  },
  props: {},
  data() {
    return {};
  },
  methods: {},
};
</script>

In custom components, how the content in the middle of the label is rendered.

1.2 Development of slots in vue

In vue 2.6.0, named slots and scoped slots introduce a new unified syntax (ie v-slot directive). It replaces slot and slot-scope, two currently deprecated but not removed features that are still useful. But in vue 3, these two will be deprecated, will not be supported or invalid.

2. Anonymous slots

<template>
  <div>
    <!-- slot You can also set the content inside, this can be set when the content is not transmitted, slot There is a default value to replace -->
    <slot>here is slot default value of</slot>
  </div>
</template>
<script>
export default {
  name: "MyButton",
  props: {},
  data() {
    return {};
  },
  methods: {},
};
</script>
<template>
  <div>
    <p>buttonTest</p>
    <my-button>
      button
    </my-button>
  </div>
</template>
<script>
import MyButton from "./MyButton.vue";

export default {
  name: "HelloWorld",
  components: {
    "my-button": MyButton,
  },
  props: {},
  data() {
    return {};
  },
  methods: {},
};
</script>
  • The anonymous method refers to sending all the content passed in when referencing the component to the location of <slot></slot> in the component page.
  • As long as there are <slot></slot> in the component, and no matter how many there are, they will all be rendered as the passed content. It means that if there are multiple <slot></slot>, the passed content will be rendered multiple times.
  • The content can also be set in <slot></slot>, this content is to ensure that there is a default value when the component is introduced. Of course, it is also possible to not set the content in <slot></slot>, so that there is no default value and no error will be reported.
  • The delivered content can also be dynamic.
  • If there is no slot to receive the delivered content, then the delivered content will be discarded and will not work.

3. Named slots

<template>
  <div>
    <slot name="icon"></slot>
    <slot name="content"></slot>
  </div>
</template>
<script>
export default {
  name: "MyButton",
  props: {},
  data() {
    return {};
  },
  methods: {},
};
</script>
<template>
  <div>
    <p>2.6.0 previous wording</p>
    <my-button>
      <!--2.6.0 previous wording-->
      <template slot='icon'>
        +
      </template>
      <template slot='content'>
        new build
      </template>
    </my-button>
    <p>--------------------------------------------</p>
    <p>2.6.0 after the wording</p>
    <my-button>
      <!--2.6.0 after the wording-->
      <template v-slot:icon>
        +
      </template>
      <template v-slot:content>
        new build
      </template>
    </my-button>
  </div>
</template>
<script>
import MyButton from "./MyButton.vue";

export default {
  name: "HelloWorld",
  components: {
    "my-button": MyButton,
  },
  props: {},
  data() {
    return {};
  },
  methods: {},
};
</script>

Named slot is to assign a name to the slot, and then one-to-one correspondence

  • Versions prior to 2.6.0
    1. If the page that introduces the component has multiple contents, it needs to be wrapped with a template, and the slot attribute and custom value should be added.
    2. The value of slot needs to correspond to the value of <slot name='xxx'></slot> name in the component.
    3. If the remaining content is not wrapped and specified, then these content will be rendered to all <slot></slot> positions in the component.
    4. If slot is set to default and name is set to default, it is the same as not setting slot and name.
    5. Compared with the named slots after vue 2.6.0, the slot='xxx' on the template only needs to be changed to v-slot:xxx, and the equal sign is changed to a colon, and the value has no quotation marks, and an error will be reported if the quotation marks are included.
    6. Named slots only need the value of the name to correspond to the value of the slot, and the order of the slots is irrelevant.
  • Versions after 2.6.0
    1. v-slot can only be used on component or template, and it will report an error if it is used on tags such as div or p
    2. slot=' xxx ' changed to v-slot:xxx, and the name after the colon cannot be quoted
    3. The content of the slot in the component page does not change
    4. After 2.6.0, the named slot v-slot:header can be abbreviated as #header, which must have parameters to write like this! #= "xxx" is not allowed, only #default = 'xxx'

4. Scope slot

<template>
  <div>
    <!--The most important thing here is :anyName=value,anyName It can also be taken at will, indicating the value to be passed in the past-->
    <slot name="icon" :anyName="defaultConfig"></slot>
    <!--The most important thing here is :anyName=value,anyName It can also be taken at will, indicating the value to be passed in the past-->
    <slot name="content" :anyName="defaultConfig"></slot>
  </div>
</template>
<script>
export default {
  name: "MyButton",
  props: {},
  data() {
    return {
      defaultConfig: {
        icon: "+",
        content: "new build",
      },
    };
  },
  methods: {},
};
</script>

<template>
  <div>
    <p>2.6.0 previous wording</p>
    <my-button>
      <!--here anyName correspond slot Transfer value :name=value middle name-->
      <template slot="icon" slot-scope="{ anyName }">
        {{ anyName.icon }}
      </template>
      <!--here obj It is a random name and does not correspond to any place-->
      <template slot="content" slot-scope="obj">
        {{ obj.anyName.content }}
      </template>
    </my-button>
    <p>--------------------------------------------</p>
    <p>2.6.0 after the wording</p>
    <my-button>
      <!--here anyName correspond slot Transfer value :name=value middle name-->
      <template v-slot:icon="{ anyName }">
        {{ anyName.icon }}
      </template>
      <!--here obj It is a random name and does not correspond to any place-->
      <template v-slot:content="obj">
        {{ obj.anyName.content }}
      </template>
    </my-button>
  </div>
</template>
<script>
import MyButton from "./MyButton.vue";

export default {
  name: "HelloWorld",
  components: {
    "my-button": MyButton,
  },
  props: {},
  data() {
    return {};
  },
  methods: {},
};
</script>
  • Versions prior to 2.6.0
    1. The scope slot is mainly to use any data of subcomponents to achieve the purpose of custom display content
    2. The most important step of the scope slot is to bind data on <slot></slot>. If there is no bound data, the parent component will only receive an empty object {}.
    3. Binding data on <slot></slot> in the scope slot can be hard-coded or dynamically bound. If it is dynamically bound, v-bind:xxx is also required
    4. The data bound on <slot></slot> in the scope slot can also pass a defined methods method with a return value
    5. When <slot></slot> is bound to data, the content sent in the place where the component is referenced can be obtained through slot-scope. The obtained content is an object
    6. slot-scope can accept any valid JavaScript expression that can appear in the parameter position of a function definition.
  • Versions after 2.6.0
    1. The two attributes are merged into one v-slot: slot name = 'passed value'.
    2. The content of the slot in the component page has not changed.
    3. v-slot cannot be used on html tags.
    4. If it is the default slot, it can be written as v-slot='xxx'.

5. Dynamic slot name

Dynamic directive arguments can also be used with v-slot to define dynamic slot names:

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

6. Deconstruction assignment of slot content

The value of v-slot is acceptable as long as it satisfies the JavaScript expression defined by the function parameter. Therefore, in supported environments (single-file or modern browsers), you can also use ES2015 destructuring syntax to extract specific interpolated content, for example:

<template>
  <div>
    <slot name="icon" :anyName="defaultConfig"></slot>
    <slot name="content" :anyName="defaultConfig"></slot>
  </div>
</template>
<script>
export default {
  name: "MyButton",
  props: {},
  data() {
    return {
      defaultConfig: {
        add: {
          icon: "+",
          content: "new build",
        },
      },
    };
  },
  methods: {},
};
</script>
<template>
  <div>
    <my-button>
      <template v-slot:icon="{ anyName }">
        {{ anyName.add.icon }}
      </template>
      <template v-slot:content="{ anyName: { add } }">
        {{ add.content }}
      </template>
    </my-button>
  </div>
</template>
<script>
import MyButton from "./MyButton.vue";

export default {
  name: "HelloWorld",
  components: {
    "my-button": MyButton,
  },
  props: {},
  data() {
    return {};
  },
  methods: {},
};
</script>

7. Comparison of versions before and after 2.6.0

Versions prior to 2.6.0Versions after 2.6.0
anonymous slotParent component: <template>content<template>
Subcomponent: <slot></slot>
Parent component: <template>content<template>
Subcomponent: <slot></slot>
named slotParent component: <template slot="slotName"><template>
Subcomponent: <slot name="slotName"></slot>
Parent component: <template v-slot:slotName><template>
Subcomponent: <slot name="slotName">
Shorthand: <template #slotName><template>
Scoped slotsParent component: <template slot="slotName" slot-scope="obj"><template>
Subcomponent: <slot name="slotName" :anyName="data"></slot>
Parent component: <template v-slot:slotName="obj"><template>
Subcomponent: <slot name="slotName" :anyName="data"></slot>
Shorthand: <template #slotName="obj"><template>
utilized locationCan be used in any tag, such as: <p slot-scope:data="test"><p>Can only be used on component or template

refer to

Tags: Vue.js Front-end

Posted by Clandestinex337 on Sat, 24 Dec 2022 20:29:01 +0530