一、Vue 3 简介与优势
Vue 3 是 Vue.js 框架的重大版本更新,于 2020 年 9 月正式发布。它带来了全新的Composition API、更好的 TypeScript 支持、更小的打包体积以及更高的性能。
主要优势:
- Composition API:提供更灵活的逻辑复用方式,解决了 Options API 在复杂组件中逻辑分散的问题。
- 性能提升:基于 Proxy 的响应式系统,初始渲染和更新速度更快,内存占用更少。
- 更好的 TypeScript 支持:源码使用 TypeScript 重写,提供完整的类型定义。
- 更小的体积:通过 Tree-shaking 优化,核心库体积减少约 40%。
- 新的内置组件:如
<Teleport>、<Suspense>等。
二、快速开始:创建 Vue 3 项目
推荐使用 Vite 创建 Vue 3 项目,速度更快,配置更简单。
# 使用 npm npm create vue@latest 或使用 yarn yarn create vue 根据提示选择项目配置(TypeScript、Router、Pinia 等)项目创建完成后,进入项目目录并安装依赖:
cd your-project-name npm install npm run dev三、核心概念:Composition API 与响应式
1. 响应式基础:ref 与 reactive
Vue 3 使用ref和reactive创建响应式数据。
<script setup> import { ref, reactive } from 'vue' // ref 用于基本类型(也可用于对象) const count = ref(0) const user = ref({ name: 'John' }) // reactive 用于对象 const state = reactive({ message: 'Hello Vue 3', list: [1, 2, 3] }) // 访问 ref 的值需要使用 .value console.log(count.value) // 0 count.value++ // reactive 对象直接访问 console.log(state.message) // 'Hello Vue 3' </script>2. 计算属性与侦听器
<script setup> import { ref, computed, watch } from 'vue' const firstName = ref('张') const lastName = ref('三') // 计算属性 const fullName = computed(() => { return firstName.value + lastName.value }) // 侦听器 watch(fullName, (newValue, oldValue) => { console.log(全名从 ${oldValue} 变为 ${newValue}) }) // 立即执行的侦听器 watch(fullName, (newValue) => { console.log(当前全名:${newValue}) }, { immediate: true }) </script>四、组件开发与通信
1. 组件定义与使用
<!-- ChildComponent.vue --> <template> <div> <h3>子组件</h3> <p>接收的消息:{{ message }}</p> <button @click="emitEvent">触发事件</button> </div> </template> <script setup> // defineProps 和 defineEmits 是编译器宏,无需导入 const props = defineProps({ message: { type: String, default: '默认消息' } }) const emit = defineEmits(['custom-event']) const emitEvent = () => { emit('custom-event', '来自子组件的数据') } </script><!-- ParentComponent.vue --> <template> <div> <h2>父组件</h2> <ChildComponent :message="parentMessage" @custom-event="handleEvent" /> </div> </template> <script setup> import { ref } from 'vue' import ChildComponent from './ChildComponent.vue' const parentMessage = ref('来自父组件的消息') const handleEvent = (data) => { console.log('收到子组件事件:', data) } </script>2. 插槽(Slots)
<!-- SlotComponent.vue --> <template> <div class="card"> <header> <slot name="header">默认标题</slot> </header> <main> <slot>默认内容</slot> </main> <footer> <slot name="footer"></slot> </footer> </div> </template><!-- 使用插槽 --> <SlotComponent> <template #header> <h2>自定义标题</h2> </template> <p>这是自定义内容</p> <template #footer> <button>确定</button> </template> </SlotComponent>五、状态管理:Pinia
Pinia 是 Vue 3 官方推荐的状态管理库,比 Vuex 更简洁、类型安全。
// stores/counter.js import { defineStore } from 'pinia' export const useCounterStore = defineStore('counter', { state: () => ({ count: 0 }), getters: { doubleCount: (state) => state.count * 2 }, actions: { increment() { this.count++ }, async incrementAsync() { await new Promise(resolve => setTimeout(resolve, 1000)) this.count++ } } })// 在组件中使用 <script setup> import { useCounterStore } from '@/stores/counter' const counter = useCounterStore() // 访问状态 console.log(counter.count) // 使用 getter console.log(counter.doubleCount) // 调用 action counter.increment() </script>六、路由管理:Vue Router 4
// router/index.js import { createRouter, createWebHistory } from 'vue-router' import Home from '../views/Home.vue' import About from '../views/About.vue' const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', component: About, meta: { requiresAuth: true } } ] const router = createRouter({ history: createWebHistory(), routes }) // 导航守卫 router.beforeEach((to, from, next) => { if (to.meta.requiresAuth && !isAuthenticated()) { next('/login') } else { next() } }) export default router七、常用 API 与技巧
1. 生命周期钩子
<script setup> import { onMounted, onUpdated, onUnmounted } from 'vue' onMounted(() => { console.log('组件挂载完成') }) onUpdated(() => { console.log('组件更新完成') }) onUnmounted(() => { console.log('组件卸载') }) </script>2. 模板引用(Template Refs)
<template> <input ref="inputRef" type="text" /> <button @click="focusInput">聚焦输入框</button> </template> <script setup> import { ref, onMounted } from 'vue' const inputRef = ref(null) const focusInput = () => { inputRef.value?.focus() } onMounted(() => { // 组件挂载后 DOM 元素才可用 console.log(inputRef.value) // <input type="text"> }) </script>八、最佳实践与常见问题
1. 性能优化
- 使用
v-once渲染静态内容 - 使用
v-memo(Vue 3.2+)缓存模板片段 - 合理使用计算属性,避免在模板中进行复杂计算
- 组件懒加载:
defineAsyncComponent
2. 常见问题
- 响应式丢失:解构 reactive 对象会失去响应性,使用
toRefs - 循环引用:避免在响应式对象中创建循环引用
- 内存泄漏:及时清理事件监听器和定时器
九、学习资源推荐
- 官方文档:Vue.js - The Progressive JavaScript Framework | Vue.js(英文)
- 中文文档:Vue.js - 渐进式 JavaScript 框架 | Vue.js
- Vue Mastery:付费视频课程,质量很高
- Vue School:免费和付费课程
- GitHub 仓库:vuejs/core