Vue.js 3.0 Tutorial
Vue.js 3.0 Component Advanced
Vue.js 3.0 Transitions & Animations
Vue.js 3.0 Reusable & Combinable
Vue.js 3.0 Advanced
Vue.js 3.0 Tools
Vue.js 3.0 Scale
Vue.js 3.0 Accessibility
Vue.js 3.0 Migrating from Vue2
Vue.js 3.0 Contribute Documentation
Vue.js 3.0 API References
Vue.js 3.0 Style Guide
The concept of slots in Vue is used for component composition. Slots give you an outlet to place content in new places or make components more reusable.
In Vue 3, there have been some changes in the syntax for slots, making them easier to read and understand.
Here is a simple example to illustrate the use of slots in Vue 3:
Let's suppose we have a reusable component called BaseLayout.vue
, which contains the structure for a page, but we want to allow content to be customized.
<!-- BaseLayout.vue --> <template> <div> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div> </template>
In the BaseLayout
component, we've specified three slots: one unnamed default slot and two named slots (header
and footer
).
Now, we'll use this BaseLayout
component in our HomePage.vue
component and fill in the slots:
<!-- HomePage.vue --> <template> <base-layout> <template #header> <h1>Here is the page title</h1> </template> <p>This is some main content for the page...</p> <template #footer> <p>Here is some footer content</p> </template> </base-layout> </template> <script> import BaseLayout from './BaseLayout.vue' export default { components: { BaseLayout } } </script>
In the HomePage
component, we're using the BaseLayout
component and providing content for the slots.
Notice the new v-slot
shorthand #
used for defining slots in Vue 3. <template #header>
is equivalent to <template v-slot:header>
in Vue 2.
The <template>
tag is a placeholder element that doesn't get rendered to the DOM itself. It's only used to apply directives to its content or slots in this case.
That's a basic introduction to using slots in Vue 3. Slots are a powerful tool for creating reusable components and can get much more complex with the use of scoped slots, which allow you to pass data from the child component back up to the parent.
Vue 3.0 Scoped Slots:
<!-- ParentComponent.vue --> <template> <ChildComponent v-slot="{ data }"> {{ data }} </ChildComponent> </template>
Vue 3.0 Slot Usage Examples:
<!-- ParentComponent.vue --> <template> <ChildComponent> <div>Slot Content</div> </ChildComponent> </template>
Vue 3.0 Slot Props:
<!-- ChildComponent.vue --> <template> <div> <slot :data="slotData"></slot> </div> </template> <!-- ParentComponent.vue --> <template> <ChildComponent v-slot="{ data }"> {{ data }} </ChildComponent> </template>
Dynamic Components in Vue 3.0:
<component :is="currentComponent"></component>
Named Slots in Vue 3.0:
<template> <BaseLayout> <template #header> <Header /> </template> <template #footer> <Footer /> </template> </BaseLayout> </template>
Composition API in Vue 3.0:
<script> import { ref, computed } from 'vue'; export default { setup() { const count = ref(0); const doubleCount = computed(() => count.value * 2); return { count, doubleCount }; }, }; </script>
Vue 3.0 v-slot Directive:
<template> <BaseLayout v-slot="{ header, footer }"> <Header :data="header" /> <Footer :data="footer" /> </BaseLayout> </template>
Vue 3.0 Slot Content Distribution:
<template> <BaseLayout> <Header /> <Content /> <Footer /> </BaseLayout> </template>
Vue 3.0 Slot Fallback Content:
<template> <BaseLayout> <template #default> Fallback Content </template> </BaseLayout> </template>
Vue 3.0 slot-scope Usage:
<template> <BaseList v-slot="{ items }"> <ul> <li v-for="item in items">{{ item.text }}</li> </ul> </BaseList> </template>
Vue 3.0 Slot Change Detection:
<template> <BaseLayout> <template #header> <Header :key="headerKey" /> </template> </BaseLayout> </template> <script> export default { data() { return { headerKey: 1, }; }, methods: { updateHeader() { this.headerKey += 1; }, }, }; </script>
Transition Effects with Slots in Vue 3.0:
Code Example:
<transition name="fade"> <slot></slot> </transition>
/* CSS for the fade transition */ .fade-enter-active, .fade-leave-active { transition: opacity 0.5s; } .fade-enter, .fade-leave-to { opacity: 0; }