Vue.js 3.0 开发指南:从入门到精通
Vue.js 3.0 是一个渐进式 JavaScript 框架,用于构建用户界面。本指南将带你深入了解 Vue 3 的核心概念、新特性和最佳实践。
2025年9月18日
DocsLib Team
Vue.jsJavaScript前端框架组件开发
Vue.js 3.0 开发指南:从入门到精通
什么是 Vue.js 3.0?
Vue.js 3.0 是一个渐进式 JavaScript 框架,用于构建用户界面。与其他大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
Vue 3 的主要特性
- Composition API:提供更灵活的代码组织方式
- 更好的 TypeScript 支持:原生 TypeScript 重写
- 性能提升:更小的包体积,更快的渲染速度
- Tree-shaking 支持:按需引入,减少包体积
- Fragment 支持:组件可以有多个根节点
- Teleport:将组件渲染到 DOM 树的任意位置
- Suspense:异步组件的加载状态处理
安装与设置
使用 Vite 创建项目
# 使用 npm
npm create vue@latest my-vue-app
# 使用 yarn
yarn create vue my-vue-app
# 使用 pnpm
pnpm create vue my-vue-app
手动安装
# 安装 Vue 3
npm install vue@next
# 安装开发工具
npm install @vitejs/plugin-vue vite --save-dev
基本项目结构
my-vue-app/
├── public/
│ └── index.html
├── src/
│ ├── components/
│ ├── views/
│ ├── App.vue
│ └── main.js
├── package.json
└── vite.config.js
核心概念
1. 响应式系统
Vue 3 使用 Proxy 实现响应式系统,提供更好的性能和更完整的语言特性支持。
import { reactive, ref, computed } from 'vue'
// 使用 ref 创建响应式数据
const count = ref(0)
// 使用 reactive 创建响应式对象
const state = reactive({
name: 'Vue 3',
version: '3.0'
})
// 计算属性
const doubleCount = computed(() => count.value * 2)
2. Composition API
Composition API 是 Vue 3 的核心特性之一,提供了更灵活的代码组织方式。
<template>
<div>
<h1>{{ title }}</h1>
<p>Count: {{ count }}</p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
</template>
<script>
import { ref, onMounted } from 'vue'
export default {
name: 'Counter',
setup() {
// 响应式数据
const title = ref('Vue 3 计数器')
const count = ref(0)
// 方法
const increment = () => {
count.value++
}
const decrement = () => {
count.value--
}
// 生命周期钩子
onMounted(() => {
console.log('组件已挂载')
})
// 返回模板需要的数据和方法
return {
title,
count,
increment,
decrement
}
}
}
</script>
3. 组件通信
Props 和 Emits
<!-- 子组件 ChildComponent.vue -->
<template>
<div>
<h3>{{ title }}</h3>
<button @click="handleClick">点击我</button>
</div>
</template>
<script>
export default {
name: 'ChildComponent',
props: {
title: {
type: String,
required: true
}
},
emits: ['custom-event'],
setup(props, { emit }) {
const handleClick = () => {
emit('custom-event', '来自子组件的数据')
}
return {
handleClick
}
}
}
</script>
<!-- 父组件 -->
<template>
<div>
<ChildComponent
:title="childTitle"
@custom-event="handleCustomEvent"
/>
</div>
</template>
<script>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
setup() {
const childTitle = ref('子组件标题')
const handleCustomEvent = (data) => {
console.log('接收到子组件数据:', data)
}
return {
childTitle,
handleCustomEvent
}
}
}
</script>
Provide/Inject
<!-- 祖先组件 -->
<script>
import { provide, ref } from 'vue'
export default {
setup() {
const theme = ref('dark')
// 提供数据
provide('theme', theme)
return {
theme
}
}
}
</script>
<!-- 后代组件 -->
<script>
import { inject } from 'vue'
export default {
setup() {
// 注入数据
const theme = inject('theme')
return {
theme
}
}
}
</script>
高级特性
1. Teleport
Teleport 允许我们将组件的一部分模板"传送"到 DOM 中的任何位置。
<template>
<div>
<h1>主要内容</h1>
<!-- 将模态框传送到 body 元素 -->
<teleport to="body">
<div v-if="showModal" class="modal">
<div class="modal-content">
<h2>模态框</h2>
<button @click="showModal = false">关闭</button>
</div>
</div>
</teleport>
<button @click="showModal = true">打开模态框</button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const showModal = ref(false)
return {
showModal
}
}
}
</script>
2. Suspense
Suspense 用于处理异步组件的加载状态。
<template>
<Suspense>
<!-- 异步组件 -->
<template #default>
<AsyncComponent />
</template>
<!-- 加载状态 -->
<template #fallback>
<div>加载中...</div>
</template>
</Suspense>
</template>
<script>
import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() =>
import('./AsyncComponent.vue')
)
export default {
components: {
AsyncComponent
}
}
</script>
3. 自定义指令
// 全局注册
app.directive('focus', {
mounted(el) {
el.focus()
}
})
// 局部注册
export default {
directives: {
focus: {
mounted(el) {
el.focus()
}
}
}
}
<template>
<input v-focus />
</template>
状态管理
使用 Pinia
Pinia 是 Vue 3 推荐的状态管理库。
npm install pinia
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
// 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++
},
decrement() {
this.count--
}
}
})
<!-- 在组件中使用 -->
<template>
<div>
<p>Count: {{ counter.count }}</p>
<p>Double: {{ counter.doubleCount }}</p>
<button @click="counter.increment">+</button>
<button @click="counter.decrement">-</button>
</div>
</template>
<script>
import { useCounterStore } from '@/stores/counter'
export default {
setup() {
const counter = useCounterStore()
return {
counter
}
}
}
</script>
路由管理
使用 Vue Router 4
npm install 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
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')
性能优化
1. 懒加载组件
const AsyncComponent = defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
2. v-memo 指令
<template>
<div v-memo="[valueA, valueB]">
<!-- 只有当 valueA 或 valueB 改变时才重新渲染 -->
</div>
</template>
3. 使用 shallowRef 和 shallowReactive
import { shallowRef, shallowReactive } from 'vue'
// 只有根级别的属性是响应式的
const state = shallowReactive({
foo: 1,
nested: {
bar: 2
}
})
// 只有 .value 是响应式的
const count = shallowRef(0)
测试
使用 Vue Test Utils
npm install @vue/test-utils vitest --save-dev
// tests/Counter.test.js
import { mount } from '@vue/test-utils'
import Counter from '@/components/Counter.vue'
describe('Counter', () => {
it('increments count when button is clicked', async () => {
const wrapper = mount(Counter)
expect(wrapper.text()).toContain('Count: 0')
await wrapper.find('button').trigger('click')
expect(wrapper.text()).toContain('Count: 1')
})
})
最佳实践
- 使用 Composition API:对于复杂组件,优先使用 Composition API
- 合理使用响应式:避免过度使用响应式,对于不需要响应式的数据使用普通变量
- 组件拆分:保持组件的单一职责,合理拆分大组件
- TypeScript 支持:在大型项目中使用 TypeScript 提高代码质量
- 性能监控:使用 Vue DevTools 监控组件性能
- 代码规范:使用 ESLint 和 Prettier 保持代码风格一致
总结
Vue.js 3.0 带来了许多激动人心的新特性和改进。Composition API 提供了更灵活的代码组织方式,更好的 TypeScript 支持使得大型项目开发更加可靠,而性能的提升让应用运行更加流畅。
通过本指南,你应该已经掌握了 Vue 3 的核心概念和主要特性。继续实践和探索,你将能够构建出更加优秀的 Vue 应用。
要了解更多信息,请访问 Vue.js 官方文档。