Vue 3 选项式 API 核心知识点与实战(十五)
- Vue.js
- 10小时前
- 3热度
- 0评论
Vue 3 作为现代前端框架中的佼佼者,其选项式 API 为开发者提供了强大的工具,帮助他们高效地管理和构建复杂的应用程序。本文将详细介绍 Vue 3 选项式 API 的核心知识点,并通过一个任务管理系统项目来巩固这些知识。通过本文的学习,你将能够熟练掌握 Vue 3 的各种选项式 API,并了解如何在实际项目中应用它们。
1. 状态管理选项
在 Vue 3 中,状态管理是构建响应式应用程序的基础。以下是几个常用的选项式 API,用于管理组件的状态:
1.1 data - 组件的数据选项
data 选项用于定义组件的初始状态。这些状态是响应式的,当它们发生变化时,Vue 会自动更新视图。
data() {
return {
count: 0
};
}1.2 props - 父组件传递的数据
props 选项用于接收父组件传递的数据。这些数据也是响应式的,可以在子组件中使用。
props: {
msg: String
}1.3 computed - 计算属性
计算属性用于定义基于组件状态(data、props)的派生值。计算属性是响应式的,当依赖的数据发生变化时,计算属性会自动重新计算。
computed: {
doubledCount() {
return this.count * 2;
}
}1.4 methods - 组件的方法
methods 选项用于定义组件的业务逻辑。这些方法可以在模板中通过事件处理器调用。
methods: {
increment() {
this.count += 1;
}
}1.5 watch - 监听数据变化
watch 选项用于监听组件的响应式数据变化,并执行回调函数。这在处理复杂的状态变化时非常有用。
watch: {
count(newVal) {
console.log(newVal);
}
}1.6 emits - 自定义事件
emits 选项用于定义组件可以触发的自定义事件。这在父子组件通信中非常常见。
emits: ['update']1.7 expose - 显式暴露属性或方法
expose 选项用于显式暴露给父组件访问的属性或方法。这在需要从父组件直接调用子组件的方法时非常有用。
expose() {
return { method };
}2. 渲染选项
渲染选项用于定义组件的模板和渲染逻辑。以下是几个常用的渲染选项:
2.1 template - 定义组件的 HTML 模板
template 选项用于定义组件的 HTML 模板。这是最常见的渲染方式。
<template>
<button @click="increment">{{ count }}</button>
</template>2.2 render - 使用渲染函数
render 选项用于使用渲染函数替代模板。这在需要更复杂的渲染逻辑时非常有用。
render(h) {
return h('button', { on: { click: this.increment } }, this.count);
}2.3 compilerOptions - 配置模板编译器
compilerOptions 选项用于配置模板编译器的选项,例如自定义插值符号。
compilerOptions: {
delimiters: ['{{', '}}']
}2.4 slots - 定义组件的插槽
slots 选项用于定义组件的插槽。插槽允许你在组件中插入内容,提高组件的复用性。
<slot></slot>3. 生命周期选项
生命周期选项用于在组件的不同生命周期阶段执行特定的操作。以下是几个常用的生命周期钩子:
3.1 beforeCreate - 组件实例化之前
beforeCreate 钩子在组件实例化之前被调用。此时,组件的数据尚未初始化。
beforeCreate() {
console.log('Before Create');
}3.2 created - 组件实例已创建
created 钩子在组件实例已创建后调用。此时,数据已经设置,但组件尚未挂载到 DOM。
created() {
console.log('Created');
}3.3 beforeMount - 挂载到 DOM 前
beforeMount 钩子在组件挂载到 DOM 前被调用。此时,模板已编译,但尚未挂载。
beforeMount() {
console.log('Before Mount');
}3.4 mounted - 组件挂载到 DOM 后
mounted 钩子在组件挂载到 DOM 后被调用。此时,可以访问到 DOM 元素。
mounted() {
console.log('Mounted');
}3.5 beforeUpdate - 数据变化后、组件重新渲染前
beforeUpdate 钩子在数据变化后、组件重新渲染前被调用。此时,可以进行一些预处理操作。
beforeUpdate() {
console.log('Before Update');
}3.6 updated - 组件更新完成后
updated 钩子在组件更新完成后被调用。此时,DOM 已经更新。
updated() {
console.log('Updated');
}3.7 beforeUnmount - 组件卸载之前
beforeUnmount 钩子在组件卸载之前被调用。此时,可以进行一些清理操作。
beforeUnmount() {
console.log('Before Unmount');
}3.8 unmounted - 组件卸载后
unmounted 钩子在组件卸载后被调用。此时,组件已经完全销毁。
unmounted() {
console.log('Unmounted');
}3.9 errorCaptured - 捕获子组件错误
errorCaptured 钩子在捕获子组件错误时被调用。这有助于集中处理错误。
errorCaptured(err, vm, info) {
console.error(err);
}3.10 renderTracked - 响应式数据变化时
renderTracked 钩子在响应式数据变化并且重新渲染时被调用。这有助于调试性能问题。
renderTracked(event) {
console.log('Render Tracked');
}3.11 renderTriggered - 响应式数据触发重新渲染时
renderTriggered 钩子在响应式数据触发重新渲染时被调用。这也有助于调试性能问题。
renderTriggered(event) {
console.log('Render Triggered');
}3.12 activated - 组件被激活时
activated 钩子在组件被激活时被调用。这仅适用于 keep-alive 组件。
activated() {
console.log('Activated');
}3.13 deactivated - 组件被停用时
deactivated 钩子在组件被停用时被调用。这仅适用于 keep-alive 组件。
deactivated() {
console.log('Deactivated');
}3.14 serverPrefetch - 服务器端渲染时
serverPrefetch 钩子在服务器端渲染时获取数据。这有助于提高首屏加载速度。
serverPrefetch() {
return fetchData();
}4. 组合选项
组合选项用于实现组件之间的依赖注入和逻辑复用。以下是几个常用的组合选项:
4.1 provide - 提供依赖
provide 选项用于提供依赖给后代组件。这在需要跨层级传递数据时非常有用。
provide('key', 'value');4.2 inject - 注入依赖
inject 选项用于从祖先组件中注入依赖。这在需要跨层级获取数据时非常有用。
inject('key');4.3 mixins - 引入外部混入
mixins 选项用于引入外部混入,以便复用逻辑。这在多个组件共享相同逻辑时非常有用。
mixins: [myMixin];4.4 extends - 组件扩展
extends 选项用于扩展另一个组件的选项。这在需要继承现有组件时非常有用。
extends: MyComponent;5. 其他杂项
除了上述选项外,还有一些其他杂项选项用于配置组件的行为。以下是几个常用的杂项选项:
5.1 name - 组件的名称
name 选项用于定义组件的名称,通常用于调试。
name: 'MyComponent';5.2 inheritAttrs - 控制属性继承
inheritAttrs 选项用于控制是否将父级组件的属性(attrs)自动继承到根元素。
inheritAttrs: false;5.3 components - 注册局部组件
components 选项用于注册局部组件,使其可以在当前组件中使用。
components: { LocalComponent };5.4 directives - 注册局部指令
directives 选项用于注册局部指令,使其可以在当前组件中使用。
directives: { focus: FocusDirective };6. 组件实例
组件实例提供了许多方法和属性,用于访问和操作组件的状态和行为。以下是几个常用的组件实例 API:
6.1 $data - 获取组件的数据对象
$data 属性用于获取组件的数据对象。
this.$data.count;6.2 $props - 获取组件的 props 对象
$props 属性用于获取组件的 props 对象。
this.$props.msg;6.3 $el - 获取组件挂载的 DOM 元素
$el 属性用于获取组件挂载的 DOM 元素。
this.$el;6.4 $options - 获取组件的配置选项
$options 属性用于获取组件的配置选项。
this.$options.name;6.5 $parent - 获取父组件的实例
$parent 属性用于获取父组件的实例。
this.$parent;6.6 $root - 获取根组件的实例
$root 属性用于获取根组件的实例。
this.$root;6.7 $slots - 获取组件的插槽内容
$slots 属性用于获取组件的插槽内容。
this.$slots.default;6.8 $refs - 获取组件的引用对象
$refs 属性用于获取组件的引用对象。
this.$refs.input;6.9 $attrs - 获取所有未绑定到组件 props 的属性
$attrs 属性用于获取所有未绑定到组件 props 的属性。
this.$attrs;6.10 $watch - 监视组件实例的响应式数据或计算属性
$watch 方法用于监视组件实例的响应式数据或计算属性。
this.$watch('count', (newCount) => {
console.log(newCount);
});6.11 $emit - 触发一个自定义事件
$emit 方法用于触发一个自定义事件。
this.$emit('update', newVal);6.12 $forceUpdate - 强制 Vue 重新渲染组件
$forceUpdate 方法用于强制 Vue 重新渲染组件。
this.$forceUpdate();6.13 $nextTick - 在下次 DOM 更新循环结束之后执行回调
$nextTick 方法用于在下次 DOM 更新循环结束之后执行回调。
this.$nextTick(() => {
console.log('DOM updated');
});实战项目:任务管理系统
接下来,我们将通过创建一个 Vue 3 任务管理系统来巩固之前学习到的知识点。这个项目将涵盖以下几个核心功能:
- 任务看板:展示任务列表,支持添加、删除和编辑任务。
- 分类筛选:支持按类别筛选任务。
- 数据持久化:使用 LocalStorage 保存任务数据。
- 深色模式切换:支持用户切换深色模式。
- 响应式设计:确保在不同设备上都能良好显示。
技术栈
- Vue 3 (Script Setup):使用最新的组合式 API。
- Vite:快速构建工具。
- Pinia:状态管理库,替代 Vuex。
- Vue Router:路由管理库。
- Element Plus:UI 组件库。
- Tailwind CSS 4.1:现代前端最流行的样式解决方案。
项目架构与环境准备
1. 创建项目
打开终端,执行以下命令创建 Vite + Vue3 项目(选择 Script Setup 语法):
npm create vite@latest task-hub -- --template vue
yarn create vite task-hub --template vue
pnpm create vite task-hub -- --template vue执行成功后,启动项目:
npm install
npm run dev启动成功后,访问终端提示的本地地址(默认 http://localhost:5173/),即可看到 Vue3 初始页面。
2. 项目目录
进入项目目录:
cd task-hub如果安装了 VS Code,可以使用 VS Code 的 code 命令打开目录:
code .3. 清理默认代码
删除 src/components/HelloWorld.vue。
清空 src/style.css。
修改 src/App.vue,代码如下:
<script setup>
import { ref, computed } from 'vue';
const newTaskTitle = ref('');
const tasks = ref([]);
const currentFilter = ref('all');
const addTask = () => {
if (newTaskTitle.value.trim()) {
tasks.value.push({ id: Date.now(), title: newTaskTitle.value, completed: false });
newTaskTitle.value = '';
}
};
const filteredTasks = computed(() => {
if (currentFilter.value === 'completed') {
return tasks.value.filter(task => task.completed);
} else if (currentFilter.value === 'active') {
return tasks.value.filter(task => !task.completed);
} else {
return tasks.value;
}
});
const toggleTask = (id) => {
const task = tasks.value.find(task => task.id === id);
if (task) {
task.completed = !task.completed;
}
};
</script>
<template>
<div class="container mx-auto p-4">
<h1 class="text-2xl font-bold mb-4">任务管理系统</h1>
<input v-model="newTaskTitle" @keyup.enter="addTask" class="w-full p-2 border rounded" placeholder="添加新任务">
<ul class="mt-4">
<li v-for="task in filteredTasks" :key="task.id" class="p-2 border-b flex justify-between items-center">
<span :class="{ 'line-through': task.completed }">{{ task.title }}</span>
<button @click="toggleTask(task.id)" class="bg-blue-500 text-white px-2 py-1 rounded">{{ task.completed ? '完成' : '未完成' }}</button>
</li>
</ul>
<div class="mt-4">
<button @click="currentFilter = 'all'" :class="{ 'bg-blue-500 text-white': currentFilter === 'all' }" class="px-2 py-1 rounded mr-2">全部</button>
<button @click="currentFilter = 'active'" :class="{ 'bg-blue-500 text-white': currentFilter === 'active' }" class="px-2 py-1 rounded mr-2">未完成</button>
<button @click="currentFilter = 'completed'" :class="{ 'bg-blue-500 text-white': currentFilter === 'completed' }" class="px-2 py-1 rounded">已完成</button>
</div>
</div>
</template>
<style>
@import "tailwindcss";
/* v4 定义主题变量的方式 */
@theme {
--color-brand: #3b82f6;
--radius-xl: 1rem;
}
/* 全局基础样式 */
@layer base {
body {
@apply bg-slate-50 text-slate-900 antialiased;
}
}
</style>核心知识点
1. 组合式 API (Composition API)
以上代码展示了 Vue 3 最核心的逻辑组织方式:
- ref (响应式基础):tasks、newTaskTitle 等都是响应式引用。在 <script> 中修改它们必须使用 .value(如 tasks.value = ...),但在 <template> 中直接写变量名。Vue 会自动追踪这些值的变化并更新 UI。
- computed (计算属性):filteredTasks 是一个非常经典的应用。它基于 tasks 和 currentFilter 派生而来。
- 优势:它是响应式的,且具有缓存性。如果 tasks 没变,多次渲染页面时,它不会重复执行过滤逻辑。
2. 列表渲染与 Key 值
<li v-for="task in filteredTasks" :key="task.id">- :key 的重要性:key 属性用于帮助 Vue 识别哪些元素发生了变化,从而高效地更新 DOM。每个列表项都应该有一个唯一的 key,以确保 Vue 能够正确地跟踪和更新列表。
总结
通过本文的学习,你已经掌握了 Vue 3 选项式 API 的核心知识点,并了解了如何在实际项目中应用它们。通过创建一个任务管理系统,你不仅巩固了这些知识,还学会了如何使用现代前端技术栈构建复杂的应用程序。希望本文对你有所帮助,祝你在 Vue 3 的开发之旅中取得更大的进步!