Vue3学习笔记

自定义组件

为了让组件更具动态性,可以通过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传递、事件处理等。通过这种方式,我们可以创建可复用、可维护的组件,从而构建复杂的应用程序。