组件基础

定义组件

<template>
    <div class="todo-item" :class="{ completed: done }">
        <input type="checkbox" :checked="done" @change="$emit('toggle')">
        <span>{{ title }}</span>
        <button @click="$emit('delete')">删除</button>
    </div>
</template>

<script setup>
defineProps({
    title: String,
    done: Boolean
})

defineEmits(['toggle', 'delete'])
</script>

<style scoped>
.todo-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px;
}
.completed span {
    text-decoration: line-through;
    color: #999;
}
</style>

组件通信

Props(父传子)

<TodoItem
    v-for="item in todos"
    :key="item.id"
    :title="item.text"
    :done="item.done"
    @toggle="toggleTodo(item.id)"
    @delete="deleteTodo(item.id)"
/>

Emit(子传父)

<button @click="$emit('delete')">删除</button>

插槽(Slot)

<!-- Card.vue -->
<template>
    <div class="card">
        <div class="header">
            <slot name="title">默认标题</slot>
        </div>
        <div class="body">
            <slot></slot>
        </div>
    </div>
</template>

生命周期

setup()          创建阶段
onBeforeMount    挂载前
onMounted        挂载后
onBeforeUpdate   更新前
onUpdated        更新后
onBeforeUnmount  卸载前
onUnmounted      卸载后