vue2 vue3 slot usage & comparison

Article directory

      • 1. vue2 slot
        • 1.1. Default slot
        • 1.2. Named slots
      • 2. vue3 socket
        • 2.1. Default slot
        • 2.2. Named slots
      • Summarize
      • Attached – Scope slot (example with vue3)

Whether it is vue2 or vue3 slots, they are divided into two types: default slots and named slots.

The advantage of the slot is that you only need to place the position of the correct slot outlet (the style is adjusted), and the order of defining the content of the slot can be arbitrary in the component, but the content of the slot with the same name will always cover the content of the previous slot ( vue2).

What is the default slot? What are named slots?
When the slot tag does not specify the name attribute, it is the default slot, otherwise it is a named slot. When defining slot content, all content that does not specify a slot name will be output to the position of the default slot, and vice versa.

  • vue2 slot, click here; vue2 component, click here
  • vue3 slot, click here; vue3 component, click here

All of the examples below are pasted and ready

1, vue2 slot

1.1, default slot

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Vue2 sockets</title>
<link rel="stylesheet" href="">
</head>
<body>
<div id="app">
{<!-- -->{ message }}
<hello-component>
<!--
The following are the content definitions of the three default slots
And the content of the last default slot will overwrite the content of the previous slot
-->

<!-- Default slot content output 1 -> The content defined in the component does not specify the slot name or specifies the slot name as default, that is, the content is output to the default slot position -->
<template>
<span style="color: red">Here is the default slot content, the font is red</span>
</template>
<!-- default slot content output 2 -> -->
<template v-slot:default>
<span style="color: green">Here is the default slot content, the font is green</span>
</template>
<!-- default slot content output 3 -> -->
<template #default>
<span style="color: yellow">Here is the default slot content, the font is yellow</span>
</template>
</hello-component>
</div>
</body>

<!-- vue3 CDN -->
<!-- <script src="//i2.wp.com/unpkg.com/vue@3/dist/vue.global.js"></script> -->

<!-- vue2 CDN -->
<script src="//i2.wp.com/cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>


<script type="text/javascript">

// Define a component first (just treat it as a component of a separate file), and define the slot outlet in the component
let HelloComponent = {<!-- -->
template:`
<div>
<div>
<!-- Default slot: The definition of the slot name attribute is not specified. This is also the content exit of the slot (the exit without the name will have the implicit name "default") ==> slot name="default" -->
<slot></slot>
</div>
</div>
`
}

var app = new Vue({<!-- -->
  el: '#app',
  data: {<!-- -->
    message: 'Hello Vue2'
  },
  // register component
  components: {<!-- -->
  HelloComponent
  }
})
</script>
</html>

Example of slot content output: last slot content overwrites all previous content
image.png

1.2, named slot

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Vue2 sockets</title>
<link rel="stylesheet" href="">
</head>
<body>
<div id="app">
{<!-- -->{ message }}
<hello-component>
<!--
The following are the content definitions of the two named slots
And the content of the last slot will overwrite the content of the previous slot
-->
<!-- Note that the abbreviated syntax of the default slot cannot be mixed with the named slot, because it will lead to ambiguous scope -->
<!-- Different versions have slightly different slot content definitions, but the end result is the same -->
<!-- Named slot content output 1 -->
<template v-slot:my-slot-name>
<span style="color: red;">Here is the content of the named slot, the font is red</span>
</template>
<!-- Named slot content output 1 -->
<template #my-slot-name>
<span style="color: green;">Here is the content of the named slot, the font is green</span>
</template>
</hello-component>
</div>
</body>

<!-- vue3 CDN -->
<!-- <script src="//i2.wp.com/unpkg.com/vue@3/dist/vue.global.js"></script> -->

<!-- vue2 CDN -->
<script src="//i2.wp.com/cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>


<script type="text/javascript">

// Define a component first (just treat it as a component of a separate file), and define the slot outlet in the component
let HelloComponent = {<!-- -->
template:`
<div>
<div>
<!-- Named slot: the name attribute is specified, the content is exported -->
<slot name="my-slot-name"></slot>
</div>
</div>
`
}

var app = new Vue({<!-- -->
  el: '#app',
  data: {<!-- -->
    message: 'Hello Vue2'
  },
  // register component
  components: {<!-- -->
  HelloComponent
  }
})
</script>
</html>

Example of slot content output: last slot content overwrites all previous content
image.png

2, vue3 slot

The coverage of slot content in vue3 is different from vue2: vue2 will always display the content of the last slot, and vue3 will display the first_template_ The content of the slot inside the tag. For specific details, you can copy the following example to experience it yourself.

2.1, default slot

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Vue3 Sockets</title>
<link rel="stylesheet" href="">
</head>
<body>
<div id="app">
{<!-- -->{ message }}
<hello-component>
<!-- vue3 slot definition -->
<!-- Method 1: Do not write the template tag, directly write the content in the component, and the content is output to the default slot by default -->
<span>Here is the default slot content, the font is black</span>
<!-- Method 3: v-slot:default definition -->
<template v-slot:default>
<span style="color: green;">Here is the default slot content, the font is green</span>
</template>
<!-- Method 2: #default definition -->
<template #default>
<span style="color: red;">Here is the default slot content, the font is red</span>
</template>
</hello-component>
</div>
</body>

<!-- vue3 CDN -->
<script src="//i2.wp.com/unpkg.com/vue@3/dist/vue.global.js"></script>

<!-- vue2 CDN -->
<!-- <script src="//i2.wp.com/cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> -->


<script type="text/javascript">

// Define a component first (just treat it as a component of a separate file), and define the slot outlet in the component
let HelloComponent = {<!-- -->
template:`
<div>
<div>
<!-- Default slot: name attribute specified, content outlet -->
<slot></slot>
</div>
</div>
`
}

const {<!-- --> createApp } = Vue
  
  createApp({<!-- -->
    data() {<!-- -->
      return {<!-- -->
        message: 'Hello Vue3!'
      }
    },
    components: {<!-- -->
HelloComponent
    }
  }).mount('#app')

</script>
</html>

Example of slot content output: shows the slot content of the first template tag
image.png

2.2, named slot

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Vue3 Sockets</title>
<link rel="stylesheet" href="">
</head>
<body>
<div id="app">
{<!-- -->{ message }}
<hello-component>
<!-- vue3 slot definition -->
<!-- Method 2: #default definition -->
<template #my-slot-name>
<span style="color: red;">Here is the content of my-slot-name named slot, the font is red</span>
</template>
<!-- Method 1: v-slot:my-slot-name definition -->
<template v-slot:my-slot-name>
<span style="color: green;">Here is the content of my-slot-name named slot, the font is green</span>
</template>
<template v-slot:my-slot-name2>
<span style="color: blue;">Here is the content of my-slot-name2 named slot, the font is blue</span>
</template>
</hello-component>
</div>
</body>

<!-- vue3 CDN -->
<script src="//i2.wp.com/unpkg.com/vue@3/dist/vue.global.js"></script>

<!-- vue2 CDN -->
<!-- <script src="//i2.wp.com/cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script> -->


<script type="text/javascript">

// Define a component first (just treat it as a component of a separate file), and define the slot outlet in the component
let HelloComponent = {<!-- -->
template:`
<div>
<div>
<!-- Named slot: the name attribute is specified, the content is exported -->
<slot name="my-slot-name2"></slot>
</div>
<div>
<!-- Named slot: the name attribute is specified, the content is exported -->
<slot name="my-slot-name"></slot>
</div>
</div>
`
}

const {<!-- --> createApp } = Vue
  
  createApp({<!-- -->
    data() {<!-- -->
      return {<!-- -->
        message: 'Hello Vue3!'
      }
    },
    components: {<!-- -->
HelloComponent
    }
  }).mount('#app')

</script>
</html>

Example of slot content output: shows the slot content of the first template tag
image.png

Summary

  1. Both vue2 and vue3 slots can use v-slot:xxx or its abbreviation #xxx to define the content;
  2. After the above tests, it is found that the slot content of vue2 is always the last to take effect, and vue3 is the first defined template tag slot content to take effect;
  3. After the above tests, it is found that in the test examples in pure native html, the named slots of vue2 and vue3 are named in the way of abc or a-b-c, and capitalization is not allowed (ABC), mixed case (aBC) are not allowed (but this problem was not found in the scaffolding);
  4. The slot content output position of vue2 and vue3 has nothing to do with the content definition position, so as long as the slot style sheet is written, the slot needs to be placed where it is needed;

Attach – Scope slot (example with vue3)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Vue3 Sockets</title>
</head>
<body>
<div id="app">
{<!-- -->{ message }}
<hello-component>
<!-- vue3 slot definition -->
<!-- scope: is the scope I specified. This scope is the scope of the slot. You can get other custom attributes on the slot except the name attribute to get the data on the slot -->
<!-- In some scenarios, the content of the slot may want to use both the data in the domain of the parent component and the domain of the child component. To do this, we need a way for the child component to provide some data to the slot when it renders -->
<template #my-slot-name="scope">
<!-- The following values will be displayed at the slot exit -->
<span style="color: red;">{<!-- -->{ scope }}</span><br>
<span style="color: red;">{<!-- -->{ scope.slotMessage }}</span><br>
<span style="color: red;">{<!-- -->{ scope.slotMessage2 }}</span><br>
</template>
</hello-component>
</div>
</body>

<!-- vue3 CDN -->
<script src="//i2.wp.com/unpkg.com/vue@3/dist/vue.global.js"></script>


<script type="text/javascript">

// Define a component first (just treat it as a component of a separate file), and define the slot outlet in the component
let HelloComponent = {<!-- -->
template:`
<div>
<div>
<!-- Named slot: the name attribute is specified, the content is exported -->
<slot name="my-slot-name" slotMessage="Hello slot" slotMessage2="Hello slot2"></slot>
</div>
</div>
`
}

const {<!-- --> createApp } = Vue
  
  createApp({<!-- -->
    data() {<!-- -->
      return {<!-- -->
        message: 'Hello Vue3!'
      }
    },
    components: {<!-- -->
HelloComponent
    }
  }).mount('#app')

</script>
</html>