自定义组件
为了让组件更具动态性,可以通过props传递数据给子组件,通过emit事件将数据传回父组件。
下边给一个具体的案例并进行详细讲解。我们将创建一个简单的待办事项列表组件。
首先,让我们创建一个TodoList.vue组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| <script setup> import { ref } from 'vue' import TodoItem from './TodoItem.vue'
const newTodo = ref('') const todos = ref([])
const addTodo = () => { if (newTodo.value.trim()) { todos.value.push({ id: Date.now(), text: newTodo.value, completed: false }) newTodo.value = '' } }
const removeTodo = (id) => { todos.value = todos.value.filter(todo => todo.id !== id) }
const toggleTodo = (id) => { const todo = todos.value.find(todo => todo.id === id) if (todo) { todo.completed = !todo.completed } } </script>
<template> <div> <h2>待办事项列表</h2> <input v-model="newTodo" @keyup.enter="addTodo" placeholder="添加新的待办事项" /> <button @click="addTodo">添加</button> <ul> <TodoItem v-for="todo in todos" :key="todo.id" :todo="todo" @remove="removeTodo" @toggle="toggleTodo" /> </ul> </div> </template>
|
然后,创建一个TodoItem.vue组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <script setup> defineProps({ todo: { type: Object, required: true } })
const emit = defineEmits(['remove', 'toggle']) </script>
<template> <li> <input type="checkbox" :checked="todo.completed" @change="emit('toggle', todo.id)" /> <span :class="{ completed: todo.completed }">{{ todo.text }}</span> <button @click="emit('remove', todo.id)">删除</button> </li> </template>
<style scoped> .completed { text-decoration: line-through; color: #999; } </style>
|
现在,让我们来详细讲解这个案例:
- 组件结构:
- 我们有一个主要的TodoList组件和一个子组件TodoItem。
- TodoList负责整体逻辑和状态管理,而TodoItem负责单个待办事项的显示和交互。
- 状态管理:
- 在TodoList中,我们使用ref来创建响应式状态:
- newTodo: 用于存储新待办事项的输入。
- todos: 用于存储所有待办事项的数组。
- 方法:
- addTodo: 添加新的待办事项到列表中。
- removeTodo: 从列表中删除指定的待办事项。
- toggleTodo: 切换指定待办事项的完成状态。
- Props传递:
- 在TodoItem组件中,我们通过defineProps定义了一个todoprop,用于接收单个待办事项的数据。
- 事件发射:
- 在TodoItem组件中,我们使用defineEmits定义了两个事件:remove和toggle。
- 这些事件在用户点击删除按钮或切换复选框时触发,并将相应的todo.id传递给父组件。
- 组件通信:
- 父组件(TodoList)通过props向子组件(TodoItem)传递数据。
- 子组件通过事件向父组件发送信息,实现了双向通信。
- 列表渲染:
- 在TodoList组件中,我们使用v-for指令来渲染TodoItem组件列表。
- 样式:
- 在TodoItem组件中,我们使用了scoped样式,确保样式只应用于当前组件。
- 我们还使用了动态类绑定来为已完成的待办事项添加删除线样式。
这个案例展示了Vue 3组件的多个重要概念,包括组件组合、状态管理、props传递、事件处理等。通过这种方式,我们可以创建可复用、可维护的组件,从而构建复杂的应用程序。