学习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>
posted @ 2025-11-11 20:33  Jade_Z  阅读(11)  评论(0)    收藏  举报