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.