Vue3 是一个现代化的 JavaScript 框架,于 2020 年 9 月正式发布。与 Vue2 相比,Vue3 带来了以下重大改进:
- 性能提升:重写虚拟 DOM,优化编译过程
- 组合式 API:更好的逻辑复用和代码组织
- 更好的 TypeScript 支持:完整的类型推导
- 更小的体积:Tree-shaking 支持,核心库约 10KB
- 新特性:Fragment、Teleport、Suspense 等
graph LR
A[Vue3核心优势] --> B[性能优化]
A --> C[组合式API]
A --> D[更好的TS支持]
A --> E[更小体积]
A --> F[新特性]
npm install -g @vue/cli
# 或
yarn global add @vue/cli
vue create my-vue-app
# 选择 Vue3 预设
npm create vite@latest my-vue-app -- --template vue
# 或
yarn create vite my-vue-app --template vue
my-vue-app/
├── public/ # 静态资源
├── src/ # 源代码
│ ├── assets/ # 资源文件
│ ├── components/ # 组件
│ ├── router/ # 路由
│ ├── store/ # 状态管理
│ ├── views/ # 页面组件
│ ├── App.vue # 根组件
│ └── main.js # 入口文件
├── .gitignore
├── package.json
└── vite.config.js # Vite 配置
选项式 API | 组合式 API |
---|---|
data , methods , computed 等选项 |
setup() 函数组织逻辑 |
逻辑分散在不同选项 | 逻辑按功能组织在一起 |
this 上下文 |
无 this ,直接访问响应式变量 |
Vue2 风格 | Vue3 推荐方式 |
<template>
<div>{{ count }}</div>
<button @click="increment">+1</button>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)
const increment = () => count.value++
</script>
<style scoped>
button {
padding: 8px 16px;
}
</style>
import { ref, computed } from 'vue'
export default {
setup() {
const count = ref(0)
const double = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, double, increment }
}
}
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
- ref: 创建响应式基本类型
- reactive: 创建响应式对象
- computed: 计算属性
- watch/watchEffect: 侦听器
- provide/inject: 依赖注入
import { ref, reactive, computed, watch } from 'vue'
// 创建响应式变量
const count = ref(0)
const state = reactive({ name: 'Vue3' })
// 计算属性
const greeting = computed(() => `Hello, ${state.name}!`)
// 侦听器
watch(count, (newVal, oldVal) => {
console.log(`Count changed from ${oldVal} to ${newVal}`)
})
graph LR
A[响应式对象] --> B[Getter]
B --> C[追踪依赖]
A --> D[Setter]
D --> E[触发更新]
特性 | ref | reactive |
---|---|---|
创建类型 | 基本类型 | 对象 |
访问值 | .value |
直接访问 |
解构 | 保持响应式 | 失去响应式 |
适用场景 | 基本类型、模板引用 | 复杂对象 |
import {
isRef,
unref,
toRef,
toRefs,
markRaw
} from 'vue'
// 检查是否为 ref
isRef(count) // true
// 解包 ref
const unwrapped = unref(count)
// 对象属性转为 ref
const nameRef = toRef(state, 'name')
// 解构保持响应式
const { name, age } = toRefs(state)
// 标记非响应式
const staticObj = markRaw({ id: 1 })
方式 | 描述 | 代码示例 |
---|---|---|
Props | 父 → 子 | <Child :msg="message" /> |
Emits | 子 → 父 | emits('update', newValue) |
Provide/Inject | 跨层级 | provide(key, value) |
Refs | 访问子组件 | <Child ref="childRef" /> |
Event Bus | 全局事件 | mitt 库 |
<!-- 父组件 -->
<ChildComponent>
<template v-slot:header>
<h1>标题</h1>
</template>
<template v-slot:default>
<p>主要内容</p>
</template>
</ChildComponent>
<!-- 子组件 -->
<div>
<slot name="header"></slot>
<slot></slot>
</div>
- Teleport: 传送组件到 DOM 其他位置
- Suspense: 异步组件加载状态处理
- KeepAlive: 缓存组件状态
- Transition: 动画过渡效果
<Teleport to="#modal-container">
<div class="modal">...</div>
</Teleport>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
npm install vue-router@4
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About }
]
const router = createRouter({
history: createWebHistory(),
routes
})
<template>
<router-link to="/">Home</router-link>
<router-view />
</template>
<script setup>
import { useRoute, useRouter } from 'vue-router'
const route = useRoute() // 当前路由信息
const router = useRouter() // 路由实例
// 导航
router.push('/about')
</script>
npm install pinia
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++
}
},
getters: {
double: (state) => state.count * 2
}
})
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
</script>
<template>
<div>{{ counter.count }}</div>
<button @click="counter.increment">+1</button>
</template>
- Vite: 极速开发服务器
- Vue DevTools: 浏览器调试工具
- ESLint: 代码规范检查
- Prettier: 代码格式化
- Vitest: 单元测试
- Cypress: E2E 测试
- Vue Testing Library: 组件测试
- Element Plus: 企业级 UI
- Vuetify: Material Design 风格
- Quasar: 跨平台解决方案
- Naive UI: TypeScript 友好
- VueUse: 常用组合式函数集合
- Axios: HTTP 客户端
- Day.js: 日期处理
- Lodash: 工具库
// 按功能组织代码
export function useUser() {
const user = ref(null)
const loading = ref(false)
async function fetchUser(id) {
loading.value = true
user.value = await api.getUser(id)
loading.value = false
}
return { user, loading, fetchUser }
}
- 使用
v-once
静态内容 - 使用
v-memo
优化渲染 - 组件懒加载
- 合理使用计算属性
<template>
<div v-memo="[value]">
<!-- 仅当 value 变化时更新 -->
</div>
</template>
- 避免使用
v-html
防止 XSS - 验证用户输入
- 使用 HTTPS
- 防止 CSRF 攻击
src/
├── composables/ # 组合式函数
├── layouts/ # 布局组件
├── plugins/ # Vue插件
├── services/ # API服务
├── utils/ # 工具函数
└── types/ # TypeScript类型定义
- Todo 应用
- 电商网站
- 博客系统
- 实时聊天应用
- 后台管理系统
学习 Vue3 是一个循序渐进的过程。建议从基础开始,逐步深入组合式 API 和响应式系统,然后学习路由和状态管理,最后探索高级特性和性能优化。多动手实践是掌握 Vue3 的关键!