Vue 3 是一个功能强大且灵活的前端框架,广泛应用于构建现代化的单页应用(SPA)
目录
[1. Vue 3 的核心精髓](#1. Vue 3 的核心精髓)
[1.1 响应式系统](#1.1 响应式系统)
[1.2 组合式 API](#1.2 组合式 API)
[1.3 性能优化](#1.3 性能优化)
[2. 基础语法](#2. 基础语法)
[2.1 创建 Vue 应用](#2.1 创建 Vue 应用)
[2.2 模板语法](#2.2 模板语法)
[3. 数据双向绑定](#3. 数据双向绑定)
[3.1 示例](#3.1 示例)
[3.2 在自定义组件中使用 v-model](#3.2 在自定义组件中使用 v-model)
[4. 自定义组件传参](#4. 自定义组件传参)
[4.1 传递 Props](#4.1 传递 Props)
[4.2 传递事件](#4.2 传递事件)
[5. 组件生命周期](#5. 组件生命周期)
[5.1 生命周期钩子(选项式 API)](#5.1 生命周期钩子(选项式 API))
[5.2 示例](#5.2 示例)
[5.3 组合式 API 中的生命周期钩子](#5.3 组合式 API 中的生命周期钩子)
[6. 路由插件的基础使用](#6. 路由插件的基础使用)
[6.1 安装 Vue Router](#6.1 安装 Vue Router)
[6.2 配置路由](#6.2 配置路由)
[6.3 在 Vue 应用中使用路由](#6.3 在 Vue 应用中使用路由)
[6.4 在组件中使用路由](#6.4 在组件中使用路由)
[7. 路由工作模式和 replace 属性](#7. 路由工作模式和 replace 属性)
[7.1 HTML5 History 模式](#7.1 HTML5 History 模式)
[7.2 Hash 模式](#7.2 Hash 模式)
[7.3 replace 属性](#7.3 replace 属性)
[8. Pinia 集中状态存储](#8. Pinia 集中状态存储)
[8.1 安装 Pinia](#8.1 安装 Pinia)
[8.2 配置 Pinia](#8.2 配置 Pinia)
[8.3 创建 Store](#8.3 创建 Store)
[8.4 使用 Store](#8.4 使用 Store)
[9. 路由嵌套和路由传参](#9. 路由嵌套和路由传参)
[9.1 路由嵌套](#9.1 路由嵌套)
[9.2 路由传参](#9.2 路由传参)
[10. Element-Plus 等 UI 库](#10. Element-Plus 等 UI 库)
[10.1 安装 Element-Plus](#10.1 安装 Element-Plus)
[10.2 全局引入 Element-Plus](#10.2 全局引入 Element-Plus)
[10.3 使用 Element-Plus 组件](#10.3 使用 Element-Plus 组件)
[10.4 使用主题和定制](#10.4 使用主题和定制)
1. Vue 3 的核心精髓
1.1 响应式系统
Vue 3 引入了全新的响应式系统,基于 Proxy
实现,相较于 Vue 2 的 Object.defineProperty
,性能更高,功能更强大。它使得数据的变化能够自动驱动视图的更新,减少手动操作的需要。
1.2 组合式 API
Vue 3 提供了组合式 API(Composition API),允许开发者在组件中更灵活地组织代码,特别适用于大型项目。与选项式 API(Options API)相比,组合式 API 更易于代码复用和逻辑组织。
1.3 性能优化
Vue 3 在编译时进行了许多优化,减少了运行时的开销,并且通过 Tree Shaking 支持更小的打包体积。
2. 基础语法
2.1 创建 Vue 应用
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
2.2 模板语法
Vue 使用基于 HTML 的模板语法,允许声明式地将 DOM 绑定到底层 Vue 实例的数据。
<template>
<div>
<p>{{ message }}</p>
<input v-model="message" />
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello Vue 3!'
}
}
}
</script>
3. 数据双向绑定
Vue 的双向绑定通过 v-model
指令实现,常用于表单输入元素。
3.1 示例
<template>
<div>
<input v-model="name" placeholder="输入名字" />
<p>你好,{{ name }}!</p>
</div>
</template>
<script>
export default {
data() {
return {
name: ''
}
}
}
</script>
3.2 在自定义组件中使用 v-model
要在自定义组件中使用 v-model
,需要在组件内部使用 modelValue
作为 prop,并通过 update:modelValue
事件来更新父组件的数据。
<!-- ChildComponent.vue -->
<template>
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</template>
<script>
export default {
props: {
modelValue: {
type: String,
default: ''
}
}
}
</script>
<!-- ParentComponent.vue -->
<template>
<ChildComponent v-model="parentValue" />
<p>父组件值:{{ parentValue }}</p>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: { ChildComponent },
data() {
return {
parentValue: ''
}
}
}
</script>
4. 自定义组件传参
在 Vue 中,组件之间的通信主要通过 props 和事件进行。父组件可以通过 props 向子组件传递数据,子组件通过事件向父组件发送消息。
4.1 传递 Props
<!-- Parent.vue -->
<template>
<Child :msg="parentMsg" />
</template>
<script>
import Child from './Child.vue'
export default {
components: { Child },
data() {
return {
parentMsg: '来自父组件的消息'
}
}
}
</script>
<!-- Child.vue -->
<template>
<div>{{ msg }}</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
required: true
}
}
}
</script>
4.2 传递事件
<!-- Child.vue -->
<template>
<button @click="notifyParent">点击通知父组件</button>
</template>
<script>
export default {
methods: {
notifyParent() {
this.$emit('childEvent', '子组件的消息')
}
}
}
</script>
<!-- Parent.vue -->
<template>
<Child @childEvent="handleChildEvent" />
</template>
<script>
import Child from './Child.vue'
export default {
components: { Child },
methods: {
handleChildEvent(message) {
console.log('收到子组件消息:', message)
}
}
}
</script>
5. 组件生命周期
Vue 组件在其生命周期中会经历多个阶段,Vue 3 提供了生命周期钩子函数来在特定阶段执行代码。
5.1 生命周期钩子(选项式 API)
阶段 | 钩子函数 |
---|---|
创建前 | beforeCreate |
创建后 | created |
挂载前 | beforeMount |
挂载后 | mounted |
更新前 | beforeUpdate |
更新后 | updated |
卸载前 | beforeUnmount |
卸载后 | unmounted |
5.2 示例
export default {
data() {
return {
count: 0
}
},
created() {
console.log('组件已创建')
},
mounted() {
console.log('组件已挂载')
},
methods: {
increment() {
this.count++
}
}
}
5.3 组合式 API 中的生命周期钩子
使用组合式 API 时,可以通过导入相应的生命周期钩子函数来使用。
import { onMounted, onUnmounted, ref } from 'vue'
export default {
setup() {
const count = ref(0)
onMounted(() => {
console.log('组件已挂载')
})
onUnmounted(() => {
console.log('组件已卸载')
})
function increment() {
count.value++
}
return {
count,
increment
}
}
}
6. 路由插件的基础使用
Vue Router 是 Vue 官方提供的路由管理器,用于构建 SPA。Vue 3 兼容 Vue Router 4。
6.1 安装 Vue Router
npm install vue-router@4
6.2 配置路由
// 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
6.3 在 Vue 应用中使用路由
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')
6.4 在组件中使用路由
<template>
<nav>
<router-link to="/">首页</router-link>
<router-link to="/about">关于</router-link>
</nav>
<router-view />
</template>
7. 路由工作模式和 replace
属性
Vue Router 提供了两种历史模式:HTML5 History 模式和 Hash 模式。
7.1 HTML5 History 模式
使用 createWebHistory()
创建路由实例时,采用的是 HTML5 History 模式。这种模式下,URL 看起来更干净,没有 #
符号。但需要服务器配置支持,确保在刷新或直接访问子路由时能够正确返回 index.html
。
7.2 Hash 模式
使用 createWebHashHistory()
创建路由实例时,采用的是 Hash 模式。URL 中会包含 #
符号,且不需要额外的服务器配置。
7.3 replace
属性
在导航时,可以使用 replace
方法或在 <router-link>
中添加 replace
属性,表示替换当前历史记录,而不是新增一条记录。
使用 replace
方法
this.$router.replace('/about')
在 <router-link>
中使用 replace
<router-link to="/about" replace>关于</router-link>
这样做的效果是,用户点击链接后不会在浏览器历史记录中新增一条记录,适用于导航到不需要返回的页面。
8. Pinia 集中状态存储
Pinia 是 Vue 3 官方推荐的状态管理库,替代了 Vuex,具有更好的类型支持和更简单的 API。
8.1 安装 Pinia
npm install pinia
8.2 配置 Pinia
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.mount('#app')
8.3 创建 Store
// 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++
}
}
})
8.4 使用 Store
<template>
<div>
<p>计数:{{ counter.count }}</p>
<p>双倍计数:{{ counter.doubleCount }}</p>
<button @click="counter.increment">增加</button>
</div>
</template>
<script>
import { useCounterStore } from '../stores/counter'
export default {
setup() {
const counter = useCounterStore()
return { counter }
}
}
</script>
9. 路由嵌套和路由传参
9.1 路由嵌套
路由嵌套允许在父路由内渲染子路由的组件。
配置嵌套路由
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import User from '../views/User.vue'
import UserProfile from '../views/UserProfile.vue'
import UserPosts from '../views/UserPosts.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/user/:id',
component: User,
children: [
{
path: 'profile',
name: 'UserProfile',
component: UserProfile
},
{
path: 'posts',
name: 'UserPosts',
component: UserPosts
}
]
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
在父组件中渲染子路由
<!-- User.vue -->
<template>
<div>
<h2>用户页面,ID:{{ $route.params.id }}</h2>
<nav>
<router-link :to="{ name: 'UserProfile', params: { id: $route.params.id } }">个人资料</router-link>
<router-link :to="{ name: 'UserPosts', params: { id: $route.params.id } }">帖子</router-link>
</nav>
<router-view />
</div>
</template>
9.2 路由传参
路由传参有两种方式:路径参数和查询参数。
路径参数
通过 URL 路径的一部分传递参数。
// 路由配置
{
path: '/user/:id',
name: 'User',
component: User
}
<!-- 导航到用户页面 -->
<router-link :to="{ name: 'User', params: { id: 123 } }">用户 123</router-link>
// 在组件中获取参数
export default {
setup() {
const route = useRoute()
const userId = route.params.id
return { userId }
}
}
查询参数
通过 URL 的查询字符串传递参数。
<!-- 导航到搜索页面 -->
<router-link :to="{ path: '/search', query: { q: 'Vue 3' } }">搜索 Vue 3</router-link>
// 在组件中获取查询参数
export default {
setup() {
const route = useRoute()
const query = route.query.q
return { query }
}
}
10. Element-Plus 等 UI 库
Element-Plus 是 Vue 3 版本的 Element UI,提供了一套丰富的组件库,帮助开发者快速构建美观的用户界面。
10.1 安装 Element-Plus
npm install element-plus
10.2 全局引入 Element-Plus
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
10.3 使用 Element-Plus 组件
<template>
<el-button type="primary" @click="handleClick">点击我</el-button>
</template>
<script>
export default {
methods: {
handleClick() {
this.$message('按钮被点击了!')
}
}
}
</script>
10.4 使用主题和定制
Element-Plus 支持定制主题,通过修改变量或使用官方提供的主题工具,可以轻松实现品牌化的界面设计。