学习Vue(11.11)
Vue3快速上手:从基础到核心语法全解析
Vue3作为Vue.js的重大升级版本,自2020年9月发布以来,凭借性能提升、源码优化和丰富新特性,成为前端开发的热门选择。本文基于官方推荐的学习路径,整理了Vue3简介、工程创建及核心语法(截至路由板块前)的关键知识点,帮助开发者快速入门Vue3开发。
一、Vue3核心优势
Vue3代号One Piece,历经4800+次提交、40+个RFC和600+次PR打造,相比Vue2有了全方位提升:
1. 性能跨越式提升
- 打包体积减少41%,加载更快
- 初次渲染快55%,更新渲染快133%,交互更流畅
- 内存占用减少54%,运行更高效
2. 源码架构升级
- 用Proxy替代defineProperty实现响应式,解决Vue2响应式缺陷
- 重写虚拟DOM和Tree-Shaking,按需打包减少冗余代码
3. 原生支持TypeScript
提供完善的类型定义,开发时类型校验更严格,大型项目维护更轻松
4. 全新特性加持
- 组合式API(Composition API):更灵活的代码组织方式
- 新内置组件:Fragment、Teleport、Suspense
- 生命周期钩子优化、data选项强制函数式声明等
二、Vue3工程创建
Vue3支持两种工程创建方式,官方推荐使用Vite构建,效率更高。
1. 基于vue-cli创建(维护模式)
适合习惯vue-cli的开发者,需确保版本≥4.5.0:
# 查看版本
vue --version
# 安装/升级
npm install -g @vue/cli
# 创建项目
vue create vue_test
# 选择3.x版本,启动项目
cd vue_test && npm run serve
2. 基于Vite创建(推荐)
Vite是新一代构建工具,热重载更快、支持按需编译,开箱即用TypeScript/JSX:
# 创建命令
npm create vue@latest
# 配置选项(示例)
√ Project name: vue3_test
√ Add TypeScript? Yes
√ Add JSX Support? No
√ Add Vue Router? No
√ Add Pinia? No
√ Add ESLint? Yes
# 启动项目
cd vue3_test && npm install && npm run dev
3. 开发工具配置
安装VSCode插件提升开发体验:
- Vue Language Features (Volar):Vue3语法支持
- TypeScript Vue Plugin (Volar):TS与Vue3协同支持
三、Vue3核心语法
1. Options API vs Composition API
- Options API:Vue2的配置式写法,数据、方法、计算属性分散在不同配置项,维护复杂需求时需来回切换
- Composition API:Vue3的组合式写法,用函数组织相关功能代码,聚合度高,复用性强
2. 核心入口:setup函数
setup是Composition API的核心,组件的所有数据、方法等都在此配置:
- 执行时机:在beforeCreate之前调用,this为undefined
- 返回值:对象可直接在模板使用,函数可自定义渲染内容
- 语法糖:
<script setup lang="ts">,无需手动返回,简化代码
语法糖优化组件命名(需安装插件):
npm i vite-plugin-vue-setup-extend -D
在vite.config.ts配置后,可直接指定组件名:
<script setup lang="ts" name="Person">
// 无需额外script标签声明组件名
</script>
3. 响应式数据创建
Vue3提供ref和reactive两种响应式创建方式,覆盖不同场景:
(1)ref:基本类型+对象类型
- 用于创建基本类型响应式数据,也支持对象类型
- JS中需通过
.value操作,模板中可直接使用
<script setup lang="ts">
import { ref } from 'vue'
// 基本类型响应式
let name = ref('张三')
// 对象类型响应式
let car = ref({ brand: '奔驰', price: 100 })
function changeName() {
name.value = '李四' // JS中需.value
car.value.price += 10 // 对象类型同样需要.value
}
</script>
(2)reactive:对象类型专用
- 仅用于创建对象/数组类型响应式数据,深层次响应式
- 无需
.value操作,直接修改属性即可
<script setup lang="ts">
import { reactive } from 'vue'
let person = reactive({
name: '张三',
age: 18,
address: { city: '北京' }
})
function changeCity() {
person.address.city = '上海' // 深层次响应式,直接修改
}
</script>
(3)ref与reactive使用原则
- 基本类型:优先用ref
- 简单对象:ref和reactive均可
- 复杂嵌套对象:优先用reactive
4. 响应式数据转换:toRefs与toRef
将响应式对象的属性转为ref对象,保持响应式关联:
- toRefs:批量转换对象所有属性
- toRef:转换单个指定属性
<script setup lang="ts">
import { reactive, toRefs, toRef } from 'vue'
let person = reactive({ name: '张三', age: 18 })
// 批量转换
let { name } = toRefs(person)
// 单个转换
let age = toRef(person, 'age')
function update() {
name.value += '~'
age.value += 1
}
</script>
5. 计算属性:computed
与Vue2功能一致,支持只读和读写两种模式:
<script setup lang="ts">
import { ref, computed } from 'vue'
let firstName = ref('zhang')
let lastName = ref('san')
// 读写模式
let fullName = computed({
get() {
return `${firstName.value}-${lastName.value}`
},
set(val) {
const [f, l] = val.split('-')
firstName.value = f
lastName.value = l
}
})
// 修改计算属性
fullName.value = 'li-si'
</script>
6. 数据监听:watch与watchEffect
(1)watch:明确指定监听目标
支持监听ref、reactive、getter函数及数组,不同场景配置不同:
<script setup lang="ts">
import { ref, reactive, watch } from 'vue'
let sum = ref(0)
let person = reactive({ name: '张三', age: 18 })
// 监听ref基本类型
watch(sum, (newVal, oldVal) => {
console.log('sum变化:', newVal, oldVal)
})
// 监听reactive对象(默认深度监听)
watch(person, (newVal) => {
console.log('person变化:', newVal)
})
// 监听对象单个属性(推荐函数式写法)
watch(() => person.name, (newVal) => {
console.log('姓名变化:', newVal)
})
(2)watchEffect:自动追踪依赖
无需指定监听目标,函数内使用的响应式数据会被自动追踪:
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
let temp = ref(0)
let height = ref(0)
// 水温≥50或水位≥20时触发
watchEffect(() => {
if (temp.value >= 50 || height.value >= 20) {
console.log('联系服务器')
}
})
7. 模板引用:ref属性
用于获取DOM节点或组件实例:
- 普通DOM标签:获取DOM元素
- 组件标签:获取组件实例(需用defineExpose暴露)
<!-- 父组件 -->
<template>
<input ref="inpt" />
<Person ref="personRef" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Person from './Person.vue'
let inpt = ref()
let personRef = ref()
// 访问DOM和组件实例
function getRefs() {
console.log(inpt.value.value) // 访问输入框值
console.log(personRef.value.name) // 访问组件暴露的属性
}
</script>
<!-- 子组件Person.vue -->
<script setup lang="ts">
import { ref, defineExpose } from 'vue'
let name = ref('张三')
// 暴露属性给父组件
defineExpose({ name })
</script>
8. 组件通信:props
父组件向子组件传递数据,支持类型限制、默认值和必要性校验:
<!-- 父组件 -->
<template>
<Person :list="persons" />
</template>
<script setup lang="ts">
import { reactive } from 'vue'
import Person from './Person.vue'
// 定义类型
interface PersonInter { id: string; name: string; age: number }
let persons = reactive<PersonInter[]>([
{ id: '1', name: '张三', age: 18 },
{ id: '2', name: '李四', age: 19 }
])
</script>
<!-- 子组件 -->
<script setup lang="ts">
import { defineProps, withDefaults } from 'vue'
interface PersonInter { id: string; name: string; age: number }
type Persons = PersonInter[]
// 带默认值的props定义
let props = withDefaults(defineProps<{ list?: Persons }>(), {
list: () => [{ id: '0', name: '默认', age: 18 }]
})
</script>
9. 生命周期钩子
Vue3重构了生命周期,移除了Vue2的beforeCreate和created(由setup替代),常用钩子:
<script setup lang="ts">
import { ref, onMounted, onUpdated, onBeforeUnmount } from 'vue'
let sum = ref(0)
// 挂载完毕
onMounted(() => {
console.log('组件挂载完成')
})
// 更新前
onUpdated(() => {
console.log('组件更新完成')
})
// 卸载前
onBeforeUnmount(() => {
console.log('组件即将卸载')
})
</script>
10. 自定义Hook
本质是封装了Composition API的函数,用于代码复用:
// hooks/useSum.ts
import { ref, onMounted } from 'vue'
export default function() {
let sum = ref(0)
const increment = () => sum.value += 1
const decrement = () => sum.value -= 1
// 挂载时自动+1
onMounted(() => increment())
return { sum, increment, decrement }
}
// 组件中使用
<script setup lang="ts">
import useSum from './hooks/useSum'
let { sum, increment } = useSum()
</script>
四、Vue3其他常用API
1. 浅层响应式:shallowRef/shallowReactive
- shallowRef:仅顶层属性响应式
- shallowReactive:仅对象顶层属性响应式
适合无需深层响应的场景,提升性能
2. 只读API:readonly/shallowReadonly
- readonly:深层只读,所有嵌套属性不可修改
- shallowReadonly:顶层只读,嵌套属性可修改
用于保护不希望被修改的状态
3. 原始对象操作:toRaw/markRaw
- toRaw:获取响应式对象的原始对象(非响应式)
- markRaw:标记对象,使其永远不会成为响应式
适合与第三方库集成时使用
4. 自定义ref:customRef
可自定义响应式逻辑,如实现防抖效果:
// hooks/useDebounceRef.ts
import { customRef } from 'vue'
export default function(initValue: string, delay = 300) {
let timer: number
return customRef((track, trigger) => ({
get() {
track() // 跟踪依赖
return initValue
},
set(value) {
clearTimeout(timer)
timer = setTimeout(() => {
initValue = value
trigger() // 触发更新
}, delay)
}
}))
}
五、Vue3新组件
1. Teleport(传送门)
将组件HTML结构移动到指定DOM位置,如弹窗挂载到body:
<template>
<teleport to="body">
<div class="modal" v-show="isShow">
<h2>弹窗内容</h2>
<button @click="isShow = false">关闭</button>
</div>
</teleport>
</template>
2. Suspense( suspense)
等待异步组件加载时显示占位内容,优化用户体验:
<script setup lang="ts">
import { defineAsyncComponent, Suspense } from 'vue'
// 异步引入组件
const Child = defineAsyncComponent(() => import('./Child.vue'))
</script>
<template>
<Suspense>
<template #default><Child /></template>
<template #fallback>加载中...</template>
</Suspense>
</template>

浙公网安备 33010602011771号