JAVASCRIPT

Advanced Scoped Slots for Flexible Vue 3 Components

Master advanced Vue 3 scoped slots to pass data from a child component back to its parent's slot content, enabling highly flexible and customizable component rendering.

// components/MyList.vue (Child Component)
// <template>
//   <div class="my-list">
//     <h3>Items:</h3>
//     <ul>
//       <li v-for="item in items" :key="item.id">
//         <slot :item="item" :remove="removeItem">
//           {{ item.name }}
//         </slot>
//       </li>
//     </ul>
//     <button @click="addItem">Add New Item</button>
//   </div>
// </template>

// <script setup>
// import { ref } from 'vue';

// const items = ref([
//   { id: 1, name: 'Apple', price: 1.20 },
//   { id: 2, name: 'Banana', price: 0.75 },
//   { id: 3, name: 'Orange', price: 1.00 }
// ]);

// const removeItem = (id) => {
//   items.value = items.value.filter(item => item.id !== id);
//   console.log(`Removed item with ID: ${id}`);
// };

// const addItem = () => {
//   const newItem = {
//     id: items.value.length ? Math.max(...items.value.map(i => i.id)) + 1 : 1,
//     name: `New Item ${items.value.length + 1}`,
//     price: Math.random() * 5
//   };
//   items.value.push(newItem);
// };
// </script>

// App.vue (Parent Component)
// <template>
//   <MyList>
//     <template v-slot="{ item, remove }">
//       <span :style="{ color: item.price > 1 ? 'green' : 'red' }">
//         {{ item.name }} - ${{ item.price.toFixed(2) }}
//       </span>
//       <button @click="remove(item.id)">X</button>
//     </template>
//   </MyList>

//   <hr />

//   <MyList>
//     <template v-slot="{ item }">
//       <em>{{ item.name }}</em>
//     </template>
//   </MyList>
// </template>

// <script setup>
// import MyList from './components/MyList.vue';
// </script>
How it works: This snippet illustrates the power of advanced scoped slots in Vue 3, allowing child components to expose data to their parent's slot content. The `MyList` component iterates through an array of `items` and renders a slot for each. Crucially, it binds `item` (the current list item) and a `remove` function to the slot, making them available as slot props to the parent. The parent `App.vue` then consumes these props using `v-slot="{ item, remove }"`, enabling it to customize the rendering of each list item while still interacting with the child's logic (like removing an item). This creates highly flexible and reusable components.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs