Vue 基础
Vue 是用于构建用户界面的渐进式 JavaScript 框架。当前主线版本为 Vue 3(2020 年发布),采用 组合式 API 与基于 Proxy 的响应式系统。前置知识:JavaScript 基础、HTML、CSS。
Vue 2 与 Vue 3
| Vue 2 | Vue 3 | |
|---|---|---|
| 响应式 | Object.defineProperty | Proxy(见 响应式) |
| 推荐 API | 选项式 API(仍支持) | 组合式 API + <script setup> |
| 构建 | Vue CLI / Webpack 常见 | Vite + @vitejs/plugin-vue 常见 |
| 状态 | Vuex 3/4 | Pinia(官方推荐) |
| 路由 | Vue Router 3 | Vue Router 4 |
新项目应使用 Vue 3 + Vite + Pinia + Vue Router 4。维护 Vue 2 项目须注意官方已结束对 Vue 2 的功能更新(仅安全相关维护期已结束,以 Vue 2 EOL 公告 为准)。
单文件组件(SFC)
.vue 文件将模板、逻辑、样式聚合:
<script setup lang="ts">
import { ref } from "vue";
const count = ref(0);
</script>
<template>
<button type="button" @click="count++">{{ count }}</button>
</template>
<style scoped>
button {
font-size: 1rem;
}
</style>
| 块 | 作用 |
|---|---|
<script setup> | 组合式逻辑;顶层绑定自动暴露给模板 |
<template> | 声明式 DOM 结构 |
<style scoped> | 仅作用于当前组件的样式(编译时加属性选择器) |
应用入口
import { createApp } from "vue";
import App from "./App.vue";
createApp(App).mount("#app");
createApp 返回应用实例,可链式注册插件(Router、Pinia)、全局组件与指令。
两种组件 API 风格
选项式 API(Options API):data、methods、computed 等选项,适合简单组件或迁移旧代码。
组合式 API(Composition API):在 setup 或 <script setup> 中使用 ref、computed、watch 等,按功能组织逻辑,便于复用(Composables)。详见 组合式 API 与设计模式。
响应式基础 API
组合式 API 最常用的四个函数:
<script setup lang="ts">
import { ref, reactive, computed, watch, watchEffect } from "vue";
// ref:包装基本类型或任意值,读写需要 .value(模板中自动解包)
const count = ref(0);
// reactive:包装对象/数组,返回 Proxy,直接读写属性
const state = reactive({ list: [1, 2, 3], keyword: "" });
// computed:派生只读值,依赖变化时自动重新计算并缓存
const doubled = computed(() => count.value * 2);
// watch:显式监听某个响应式源,可拿到旧值/新值,适合处理副作用
watch(count, (newVal, oldVal) => {
console.log(`count: ${oldVal} -> ${newVal}`);
});
// watchEffect:立即执行一次,并自动追踪函数内用到的所有响应式依赖
watchEffect(() => {
console.log("keyword changed:", state.keyword);
});
</script>
| API | 适用场景 |
|---|---|
ref | 基本类型、需要整体替换的值、组件间传递单个值 |
reactive | 内部字段较多、需要直接属性访问的对象状态 |
computed | 由其他状态派生、需要缓存的只读值 |
watch | 需要明确知道“监听谁”、拿到新旧值、按需触发副作用 |
watchEffect | 依赖较多且不想手动列出、只关心“最新一次执行” |
常用指令速查
| 指令 | 作用 | 示例 |
|---|---|---|
v-if / v-else-if / v-else | 条件渲染(销毁/重建 DOM) | <p v-if="ok">Yes</p> |
v-show | 条件显示(只切换 display,DOM 不销毁) | <p v-show="ok">Yes</p> |
v-for | 列表渲染,务必配合 :key | <li v-for="item in list" :key="item.id"> |
v-bind / : | 绑定属性 | <img :src="url"> |
v-on / @ | 绑定事件 | <button @click="onClick"> |
v-model | 表单双向绑定 | <input v-model="text"> |
v-slot / # | 具名/作用域插槽 | <template #header> |
v-if 与 v-for 不建议在同一元素上同时使用(优先级和可读性问题),需要时把 v-if 提到外层或用 computed 先过滤列表。
生命周期钩子(组合式 API)
| 钩子 | 触发时机 |
|---|---|
onBeforeMount | 组件挂载前 |
onMounted | 组件挂载完成,可访问 DOM、发起初始请求 |
onBeforeUpdate | 响应式状态变化、DOM 更新前 |
onUpdated | DOM 更新完成后 |
onBeforeUnmount | 组件卸载前,适合清理定时器、事件监听 |
onUnmounted | 组件卸载完成后 |
<script setup lang="ts">
import { onMounted, onBeforeUnmount } from "vue";
let timer: number;
onMounted(() => {
timer = window.setInterval(() => console.log("tick"), 1000);
});
onBeforeUnmount(() => clearInterval(timer));
</script>
组件通信基础
<!-- Child.vue -->
<script setup lang="ts">
const emit = defineEmits<{ update: [value: string] }>();
</script>
<template>
<button @click="emit('update', 'hi')">Send</button>
</template>
官方生态(常用)
| 库 | 用途 |
|---|---|
| Vue Router | 客户端路由 |
| Pinia | 状态管理 |
| Vite | 开发与构建 |
| VueUse | 组合式工具函数集合 |
| Nuxt | 基于 Vue 的全栈/SSR 框架(可选) |
深度集成见 生态。
常见坑
reactive解构后失去响应式:const { list } = state得到的是普通值,需要toRefs(state)或直接访问state.list。ref忘记.value:在<script>中(模板里不需要)忘记.value会导致拿到的是RefImpl对象而不是实际值。v-for不写:key或用index作 key:列表增删时会导致 DOM 复用错乱、动画/输入框状态错位,尽量用稳定的业务 ID。- 直接修改
props:props是只读的,子组件需要“修改”时应emit事件让父组件更新,或用computed生成本地派生值。 - 在
watchEffect里产生死循环:如果回调内又修改了它所依赖的响应式数据,会不断触发自身,注意拆分读/写逻辑。
最佳实践
- 新项目统一用
<script setup lang="ts">,减少样板代码并获得更好的类型推断。 - 复杂表单/列表状态优先
reactive,跨组件共享的原子值优先ref。 - 把可复用的响应式逻辑抽成 Composable(
useXxx函数),而不是在组件里堆逻辑。 - 组件样式默认加
scoped,需要覆盖子组件样式时用:deep()而不是去掉scoped。 - 生命周期里注册的副作用(定时器、事件监听、订阅)务必在
onBeforeUnmount中清理。
本目录学习路径
| 主题 | 文档 |
|---|---|
| 响应式原理 | v2-v3 → track → proxy 进阶 |
| 组件设计 | design、props |
| 路由与状态 | router、status |
| 渲染与 TS | render、typescript |
| 性能 | performance/build 等 |
| 工程与测试 | project、test |
参考文献
以下链接在编写时均可正常访问:
| 资料 | 说明 |
|---|---|
| Vue 官方文档 | 中文文档 |
| Vue 3 迁移指南 | 从 Vue 2 迁移(英文) |
| MDN:Vue(入门) | MDN 教程 |
相关文章
资源优化
图片懒加载、按需引入与 Web Vitals 监控。见 HTML 图片、CSS 字体优化。
状态管理:Pinia 与 Vuex
Pinia 是 Vue 官方推荐的状态管理库(Vue 3 新项目默认选型)。Vuex 4 仍可与 Vue 3 配合,用于维护旧项目。见 Vue 基础。
Vue 生态关键库深度集成
VueUse、Vite 与 Nuxt 是 Vue 3 生态中常用的效率与工程化方案。概览见 Vue 基础。
依赖收集与派发更新机制
说明 Vue 3 中 track / trigger 与 targetMap 的工作方式。前置:v2-v3 差异。
测试策略
Vue 应用常用 Vitest + @vue/test-utils 做单元/组件测试,Playwright 或 Cypress 做 E2E。见 Vue 基础。
组合式 API 与逻辑复用设计模式
组合式 API 与 Composables 是 Vue 3 推荐的逻辑组织方式。概览见 Vue 基础。