Vue3 学习教程,从入门到精通,Vue 3 选项式 API 语法知识点与案例详解(33)
Vue 3 选项式 API 语法知识点与案例详解
Vue 3 提供了两种主要的 API 风格:组合式 API(Composition API)和选项式 API(Options API)。对于初学者来说,选项式 API 更加直观和易于理解。以下将详细介绍 Vue 3 选项式 API 的所有主要语法知识点,并通过一个完整的案例代码进行演示,代码中包含详细的中文注释。
一、选项式 API 语法知识点
1. 数据选项 (data
)
用于定义组件的响应式数据。
data() {return {message: 'Hello, Vue 3!'};
}
2. 方法选项 (methods
)
用于定义组件内可调用的方法。
methods: {greet() {console.log(this.message);}
}
3. 计算属性 (computed
)
用于定义基于其他数据计算得出的属性,具有缓存机制。
computed: {reversedMessage() {return this.message.split('').reverse().join('');}
}
4. 侦听器 (watch
)
用于监听数据的变化,并在数据变化时执行特定操作。
watch: {message(newVal, oldVal) {console.log(`Message changed from ${oldVal} to ${newVal}`);}
}
5. 生命周期钩子
用于在组件生命周期的不同阶段执行代码。
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeUnmount
unmounted
activated
deactivated
errorCaptured
renderTracked
renderTriggered
mounted() {console.log('组件已挂载');
}
6. 模板语法 (template
)
用于定义组件的 HTML 结构,可以使用 Vue 的指令(如 v-bind
, v-if
, v-for
等)。
<template><div>{{ message }}</div>
</template>
7. 指令
Vue 提供的特殊属性,用于在模板中实现各种功能。
v-bind
(:
): 绑定属性v-if
,v-else-if
,v-else
: 条件渲染v-for
: 列表渲染v-on
(@
): 事件监听v-model
: 双向数据绑定v-show
: 显示/隐藏元素(通过 CSS)
8. 组件通信
- Props: 父组件向子组件传递数据。
- Emit: 子组件向父组件发送事件。
- Provide/Inject: 祖先组件向后代组件提供数据。
9. 插槽 (slots
)
用于在组件中插入内容。
<template><slot></slot>
</template>
10. 混入 (mixins
)
用于在多个组件之间复用逻辑。
const myMixin = {data() {return {mixinData: 'Mixin Data'};},methods: {mixinMethod() {console.log('Mixin Method');}}
};export default {mixins: [myMixin],// 其他选项
}
11. 自定义指令
用于创建自定义指令以扩展 Vue 的功能。
Vue.directive('focus', {inserted(el) {el.focus();}
});
12. 过渡与动画
用于在元素状态变化时应用动画效果。
<transition name="fade"><p v-if="show">Hello</p>
</transition>
.fade-enter-active, .fade-leave-active {transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {opacity: 0;
}
二、案例代码详解
以下是一个简单的 Vue 3 选项式 API 案例:一个待办事项(Todo)应用。该应用允许用户添加、删除和标记待办事项为完成状态。
1. 项目结构
src/
├─ components/
│ └─ TodoList.vue
├─ App.vue
└─ main.js
2. main.js
// main.js
import { createApp } from 'vue';
import App from './App.vue';createApp(App).mount('#app');
3. App.vue
<!-- App.vue -->
<template><div id="app"><h1>Vue 3 待办事项应用</h1><TodoList /></div>
</template><script>
import TodoList from './components/TodoList.vue';export default {name: 'App',components: {TodoList}
};
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;text-align: center;margin-top: 60px;
}
</style>
4. TodoList.vue
<!-- TodoList.vue -->
<template><div><h2>我的待办事项</h2><form @submit.prevent="addTodo"><input v-model="newTodo" placeholder="添加新的待办事项" /><button type="submit">添加</button></form><ul><li v-for="(todo, index) in todos" :key="index" :class="{ completed: todo.completed }"><input type="checkbox" v-model="todo.completed" /><span>{{ todo.text }}</span><button @click="removeTodo(index)">删除</button></li></ul><p>已完成: {{ completedCount }} / {{ todos.length }}</p></div>
</template><script>
export default {name: 'TodoList',data() {return {newTodo: '',todos: []};},computed: {completedCount() {return this.todos.filter(todo => todo.completed).length;}},methods: {addTodo() {const trimmedTodo = this.newTodo.trim();if (trimmedTodo) {this.todos.push({text: trimmedTodo,completed: false});this.newTodo = '';}},removeTodo(index) {this.todos.splice(index, 1);}},watch: {todos: {handler(newTodos) {// 将待办事项保存到本地存储localStorage.setItem('todos', JSON.stringify(newTodos));},deep: true}},mounted() {// 从本地存储中加载待办事项const storedTodos = localStorage.getItem('todos');if (storedTodos) {this.todos = JSON.parse(storedTodos);}}
};
</script><style scoped>
.completed {text-decoration: line-through;color: gray;
}input[type="text"] {padding: 8px;width: 200px;margin-right: 10px;
}button {padding: 8px 12px;margin-left: 5px;
}ul {list-style-type: none;padding: 0;margin-top: 20px;
}li {margin: 5px 0;display: flex;align-items: center;
}li span {margin-left: 10px;flex: 1;
}li button {margin-left: 10px;
}
</style>
5. 代码详解
a. 数据 (data
)
data() {return {newTodo: '',todos: []};
}
newTodo
: 用于存储用户输入的新的待办事项。todos
: 存储所有待办事项的数组。
b. 计算属性 (computed
)
computed: {completedCount() {return this.todos.filter(todo => todo.completed).length;}
}
completedCount
: 计算已完成待办事项的数量。
c. 方法 (methods
)
methods: {addTodo() {const trimmedTodo = this.newTodo.trim();if (trimmedTodo) {this.todos.push({text: trimmedTodo,completed: false});this.newTodo = '';}},removeTodo(index) {this.todos.splice(index, 1);}
}
addTodo
: 添加新的待办事项。如果输入不为空,则将其添加到todos
数组中,并清空输入框。removeTodo
: 根据索引删除指定的待办事项。
d. 侦听器 (watch
)
watch: {todos: {handler(newTodos) {// 将待办事项保存到本地存储localStorage.setItem('todos', JSON.stringify(newTodos));},deep: true}
}
- 监听
todos
数组的变化,并将最新的数据保存到本地存储中,以便在页面刷新后数据不会丢失。
e. 生命周期钩子 (mounted
)
mounted() {// 从本地存储中加载待办事项const storedTodos = localStorage.getItem('todos');if (storedTodos) {this.todos = JSON.parse(storedTodos);}
}
- 在组件挂载后,从本地存储中加载已保存的待办事项。
f. 模板 (template
)
<template><div><h2>我的待办事项</h2><form @submit.prevent="addTodo"><input v-model="newTodo" placeholder="添加新的待办事项" /><button type="submit">添加</button></form><ul><li v-for="(todo, index) in todos" :key="index" :class="{ completed: todo.completed }"><input type="checkbox" v-model="todo.completed" /><span>{{ todo.text }}</span><button @click="removeTodo(index)">删除</button></li></ul><p>已完成: {{ completedCount }} / {{ todos.length }}</p></div>
</template>
- 表单 (
form
): 使用@submit.prevent
防止表单的默认提交行为,调用addTodo
方法。 - 输入框 (
input
): 使用v-model
实现双向数据绑定,绑定到newTodo
。 - 列表 (
ul
): 使用v-for
指令遍历todos
数组,渲染每个待办事项。 - 复选框 (
input[type="checkbox"]
): 使用v-model
绑定todo.completed
,实现双向数据绑定。 - 删除按钮 (
button
): 绑定@click
事件,调用removeTodo
方法,删除对应的待办事项。 - 样式 (
style
): 使用scoped
属性,确保样式仅作用于当前组件。
三、运行效果
- 添加待办事项: 在输入框中输入文本,点击“添加”按钮,待办事项会出现在列表中。
- 标记完成: 点击复选框,待办事项会被标记为完成,文本会显示为删除线。
- 删除待办事项: 点击“删除”按钮,对应的待办事项会被移除。
- 数据持久化: 刷新页面后,已添加的待办事项会从本地存储中加载,保持数据不丢失。
四、总结
通过上述案例,我们全面展示了 Vue 3 选项式 API 的主要语法知识点,包括数据管理、方法调用、计算属性、侦听器、生命周期钩子、模板语法、指令、组件通信等。通过这个简单的待办事项应用,读者可以更好地理解 Vue 3 选项式 API 的基本使用方式,并为进一步学习组合式 API 打下基础。