FORMA

Vue 基础

Vue 是用于构建用户界面的渐进式 JavaScript 框架。当前主线版本为 Vue 3(2020 年发布),采用 组合式 API 与基于 Proxy 的响应式系统。前置知识:JavaScript 基础HTMLCSS

Vue 2 与 Vue 3

Vue 2Vue 3
响应式Object.definePropertyProxy(见 响应式
推荐 API选项式 API(仍支持)组合式 API + <script setup>
构建Vue CLI / Webpack 常见Vite + @vitejs/plugin-vue 常见
状态Vuex 3/4Pinia(官方推荐)
路由Vue Router 3Vue Router 4

新项目应使用 Vue 3 + Vite + Pinia + Vue Router 4。维护 Vue 2 项目须注意官方已结束对 Vue 2 的功能更新(仅安全相关维护期已结束,以 Vue 2 EOL 公告 为准)。

单文件组件(SFC)

.vue 文件将模板、逻辑、样式聚合:

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>仅作用于当前组件的样式(编译时加属性选择器)

应用入口

js
import { createApp } from "vue";
import App from "./App.vue";

createApp(App).mount("#app");

createApp 返回应用实例,可链式注册插件(Router、Pinia)、全局组件与指令。

两种组件 API 风格

选项式 API(Options API):datamethodscomputed 等选项,适合简单组件或迁移旧代码。

组合式 API(Composition API):在 setup<script setup> 中使用 refcomputedwatch 等,按功能组织逻辑,便于复用(Composables)。详见 组合式 API 与设计模式

响应式基础 API

组合式 API 最常用的四个函数:

vue
<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-ifv-for 不建议在同一元素上同时使用(优先级和可读性问题),需要时把 v-if 提到外层或用 computed 先过滤列表。

生命周期钩子(组合式 API)

钩子触发时机
onBeforeMount组件挂载前
onMounted组件挂载完成,可访问 DOM、发起初始请求
onBeforeUpdate响应式状态变化、DOM 更新前
onUpdatedDOM 更新完成后
onBeforeUnmount组件卸载前,适合清理定时器、事件监听
onUnmounted组件卸载完成后
vue
<script setup lang="ts">
import { onMounted, onBeforeUnmount } from "vue";

let timer: number;
onMounted(() => {
    timer = window.setInterval(() => console.log("tick"), 1000);
});
onBeforeUnmount(() => clearInterval(timer));
</script>

组件通信基础

  • 父传子props(详见 props)。
  • 子传父emit 自定义事件,父组件用 @事件名 监听。
  • 跨层级provide/inject,或使用 Pinia 集中状态。
vue
<!-- 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。
  • 直接修改 propsprops 是只读的,子组件需要“修改”时应 emit 事件让父组件更新,或用 computed 生成本地派生值。
  • watchEffect 里产生死循环:如果回调内又修改了它所依赖的响应式数据,会不断触发自身,注意拆分读/写逻辑。

最佳实践

  1. 新项目统一用 <script setup lang="ts">,减少样板代码并获得更好的类型推断。
  2. 复杂表单/列表状态优先 reactive,跨组件共享的原子值优先 ref
  3. 把可复用的响应式逻辑抽成 Composable(useXxx 函数),而不是在组件里堆逻辑。
  4. 组件样式默认加 scoped,需要覆盖子组件样式时用 :deep() 而不是去掉 scoped
  5. 生命周期里注册的副作用(定时器、事件监听、订阅)务必在 onBeforeUnmount 中清理。

本目录学习路径

主题文档
响应式原理v2-v3trackproxy 进阶
组件设计designprops
路由与状态routerstatus
渲染与 TSrendertypescript
性能performance/build
工程与测试projecttest

参考文献

以下链接在编写时均可正常访问:

资料说明
Vue 官方文档中文文档
Vue 3 迁移指南从 Vue 2 迁移(英文)
MDN:Vue(入门)MDN 教程

Series

vue

2 / 16