文章目录
-
- [一、Vue 3 核心架构:三层结构](#一、Vue 3 核心架构:三层结构)
-
- [1. 脚本逻辑层:`<script setup>`](#1. 脚本逻辑层:
<script setup>) - [2. 视图模板层:`<template>`](#2. 视图模板层:
<template>) - [3. 样式层:`<style scoped>`](#3. 样式层:
<style scoped>)
- [1. 脚本逻辑层:`<script setup>`](#1. 脚本逻辑层:
- [二、响应式核心:ref 和 reactive](#二、响应式核心:ref 和 reactive)
-
- [1. ref:通用响应式 API](#1. ref:通用响应式 API)
- [2. reactive:仅支持引用类型](#2. reactive:仅支持引用类型)
- [3. ref vs reactive 对比](#3. ref vs reactive 对比)
- 三、组件通信:Props、defineExpose
-
- [1. 父传子:Props(单向数据流)](#1. 父传子:Props(单向数据流))
- [2. 父取子数据:defineExpose](#2. 父取子数据:defineExpose)
- 四、常用高级特性
-
- [1. 计算属性:computed](#1. 计算属性:computed)
- [2. 监听器:watch & watchEffect](#2. 监听器:watch & watchEffect)
-
- (1)watch:显式监听
- (2)watchEffect:自动收集依赖
- [watch vs computed 区别](#watch vs computed 区别)
- [3. 遍历:v-for](#3. 遍历:v-for)
- [4. 双向绑定:v-model](#4. 双向绑定:v-model)
- [5. 响应式解构:toRef & toRefs](#5. 响应式解构:toRef & toRefs)
- [6. 生命周期](#6. 生命周期)
- [7. Hook:逻辑复用](#7. Hook:逻辑复用)
-
- [步骤1:创建 Hook 文件(useCount.js)](#步骤1:创建 Hook 文件(useCount.js))
- [步骤2:组件中使用 Hook](#步骤2:组件中使用 Hook)
- 五、实用工具
-
- [1. 路径别名:@](#1. 路径别名:@)
- [2. Vue 开发者工具](#2. Vue 开发者工具)
- 六、总结
一、Vue 3 核心架构:三层结构
Vue 3 组件的核心由三层结构组成,逻辑、视图、样式各司其职,也是组合式 API 推荐的代码组织方式:
vue
<script setup lang="ts">
// 1. 脚本逻辑层:数据、方法、生命周期、响应式变量等核心逻辑
</script>
<template>
<!-- 2. 视图模板层:HTML 结构 + Vue 模板语法 -->
</template>
<style scoped>
/* 3. 样式层:组件样式(scoped 实现样式隔离) */
</style>
1. 脚本逻辑层:<script setup>
<script setup> 是 Vue 3 组合式 API 的语法糖,也是官方推荐写法,核心特点:
- 无需
export default,直接编写逻辑; - 变量、函数默认暴露给
<template>,无需手动return; - 彻底脱离
this(写this会报错/返回undefined); - 支持顶层
await、自动导入、简洁的组件注册; lang="ts"可直接开启 TypeScript 支持。
2. 视图模板层:<template>
负责渲染页面 DOM 结构,核心规则:
- 支持 Vue 模板语法:插值
{``{ }}、指令v-if/v-for/v-bind、事件绑定@click等; - Vue 3 支持多根节点,但推荐单根节点(更兼容);
- 可直接使用
<script setup>中定义的变量和方法。
3. 样式层:<style scoped>
负责组件样式,关键特性:
scoped:样式仅作用于当前组件(Vue 自动添加data-v-xxx属性实现隔离);- 支持 SCSS/LESS 等预处理器(通过
lang="scss"开启); - 无
scoped时为全局样式,谨慎使用避免冲突。
二、响应式核心:ref 和 reactive
Vue 3 响应式的核心是「数据变 → 视图自动更新」,主要通过 ref 和 reactive 实现,二者各有适用场景。
1. ref:通用响应式 API
支持基本类型 + 引用类型,是最通用的响应式方案:
vue
<script setup>
import { ref } from 'vue'
// 基本类型响应式
const count = ref(0)
// 引用类型响应式
const user = ref({ name: "张三", age: 18 })
// 脚本中必须通过 .value 访问/修改
count.value = 1
user.value.name = "李四"
</script>
<template>
<!-- 模板中自动解包,无需 .value -->
<div>{{ count }}</div>
<div>{{ user.name }}</div>
</template>
实用技巧 :用 ref 替代 document 获取 DOM/组件
vue
<script setup>
import { ref, onMounted } from 'vue'
// 定义 ref 关联 DOM(变量名需与模板 ref 一致)
const myDiv = ref(null)
onMounted(() => {
// 页面挂载后获取 DOM 内容(避免元素未生成导致获取不到)
console.log(myDiv.value.innerText)
})
</script>
<template>
<div ref="myDiv">Hello Vue</div>
</template>
2. reactive:仅支持引用类型
仅适用于 Object/Array/Map/Set 等复杂引用类型,不支持基本类型(会丢失响应式):
vue
<script setup>
import { reactive } from 'vue'
const state = reactive({ count: 0, list: [1, 2, 3] })
// 直接操作属性,无需 .value
state.count = 1
state.list.push(4)
</script>
3. ref vs reactive 对比
| 特性 | ref | reactive |
|---|---|---|
| 支持类型 | 基本类型 + 对象/数组 | 仅对象/数组等引用类型 |
| 取值方式 | 脚本 .value,模板自动解包 |
直接点属性(无需 .value) |
| 重新赋值 | 可整体替换(refObj.value = 新值) |
直接替换整个对象会丢失响应(可用 Object.assign) |
| 解构 | 解构不丢失响应 | 直接解构丢失响应 |
三、组件通信:Props、defineExpose
组件通信是 Vue 开发的核心场景,重点掌握「父传子」和「子传父/父取子数据」。
1. 父传子:Props(单向数据流)
Props 是父组件向子组件传数据的核心方式,遵循「单向只读」规则(子组件不能直接修改 Props)。
步骤1:父组件传数据
vue
<!-- Parent.vue -->
<template>
<!-- 用 : 绑定要传递的属性 -->
<Child :msg="parentMsg" :num="100" :user="userInfo" />
</template>
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'
const parentMsg = ref("我是父组件的数据")
const userInfo = ref({ name: "张三" })
</script>
步骤2:子组件声明接收
子组件通过 defineProps 声明接收(无需导入),支持两种写法:
vue
<!-- Child.vue -->
<script setup>
// 写法1:数组(简单无校验)
const props = defineProps(['msg', 'num', 'user'])
// 写法2:对象(推荐,带类型/默认值/必填校验)
const props = defineProps({
msg: {
type: String,
required: true // 必传
},
num: {
type: Number,
default: 0 // 默认值
},
user: {
type: Object,
default: () => ({}) // 对象默认值推荐用函数
}
})
// 脚本中使用 Props
console.log(props.msg)
</script>
<template>
<!-- 模板中直接使用 -->
<div>{{ msg }}</div>
<div>{{ num }}</div>
</template>
核心规则
- 单向数据流:子组件修改 Props 会报警告,需通知父组件修改原始数据;
- 响应式:父组件数据变化,子组件 Props 自动更新;
- 命名:父组件传值支持驼峰/短横线(如
:userName或:user-name)。
2. 父取子数据:defineExpose
子组件需通过 defineExpose 暴露数据/方法,父组件才能获取:
vue
<!-- Child.vue -->
<script setup>
import { ref } from 'vue'
const childCount = ref(0)
const add = () => {
childCount.value++
}
// 暴露给父组件的属性/方法
defineExpose({
childCount,
add
})
</script>
vue
<!-- Parent.vue -->
<template>
<Child ref="childRef" />
<button @click="getChildData">获取子组件数据</button>
</template>
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
const childRef = ref(null)
const getChildData = () => {
// 获取子组件暴露的属性
console.log(childRef.value.childCount)
// 调用子组件暴露的方法
childRef.value.add()
}
</script>
四、常用高级特性
1. 计算属性:computed
根据依赖数据自动计算新值,自带缓存(依赖不变时不会重复计算),适合数据加工、拼接、过滤等场景:
vue
<script setup>
import { ref, computed } from 'vue'
const count = ref(1)
// 基础写法:只读
const doubleCount = computed(() => {
return count.value * 2
})
// 完整写法:可读写
const fullName = computed({
get() {
return `${firstName.value} ${lastName.value}`
},
set(val) {
const [first, last] = val.split(' ')
firstName.value = first
lastName.value = last
}
})
</script>
<template>
<!-- 像普通变量一样使用,无需加 () -->
<div>{{ doubleCount }}</div>
</template>
2. 监听器:watch & watchEffect
监听数据变化并执行逻辑,适合异步请求、表单监听、复杂逻辑处理等场景。
(1)watch:显式监听
需指定监听目标,支持配置深度监听、立即执行:
vue
<script setup>
import { ref, reactive, watch } from 'vue'
// 1. 监听普通 ref
const count = ref(0)
watch(count, (newVal, oldVal) => {
console.log('count变了:', newVal)
})
// 2. 监听 reactive 对象(自带深度监听)
const user = reactive({ name: "张三", age: 18 })
watch(user, () => {
console.log('user内部属性变了')
})
// 3. 监听对象单个属性(需用函数返回)
watch(() => user.age, (newVal) => {
console.log('年龄变了:', newVal)
})
// 4. 监听多个值(数组形式)
watch([count, () => user.age], ([newCount, newAge]) => {
console.log('count或年龄变了')
})
// 5. 配置立即执行 + 深度监听
watch(() => user, () => {}, {
immediate: true, // 页面加载时执行一次
deep: true // 监听对象内部属性(ref 对象需手动开启)
})
</script>
(2)watchEffect:自动收集依赖
无需指定监听目标,自动监听函数内用到的响应式数据,初始化即执行:
vue
<script setup>
import { ref, watchEffect } from 'vue'
const count = ref(0)
// 自动监听 count,初始化执行一次
watchEffect(() => {
console.log('count值:', count.value)
})
</script>
watch vs computed 区别
computed:计算新值,带缓存,必须return,适合数据加工;watch:监听变化执行逻辑,无需return,适合异步/复杂操作。
3. 遍历:v-for
遍历数组/对象渲染DOM,核心规则(必记):
- 必须加
:key(避免渲染错乱,推荐用唯一标识,如 ID); - 不要和
v-if写在同一个标签(优先级问题导致逻辑异常); - 遍历后的
item仅在当前标签内有效; - 数组修改后,Vue 自动更新视图。
4. 双向绑定:v-model
专门用于表单元素,实现「数据变 → 视图变;视图变 → 数据变」:
vue
<script setup>
import { ref } from 'vue'
const username = ref('')
</script>
<template>
<!-- 输入框双向绑定 -->
<input v-model="username" placeholder="请输入用户名" />
<!-- 实时显示输入内容 -->
<div>你输入了:{{ username }}</div>
</template>
5. 响应式解构:toRef & toRefs
reactive 对象直接解构会丢失响应式,toRef/toRefs 可保留响应式:
toRef:复制reactive单个属性,保留响应式;toRefs:复制reactive所有属性,保留响应式。
vue
<script setup>
import { reactive, toRef, toRefs } from 'vue'
const user = reactive({ name: "张三", age: 18 })
// 单个属性响应式解构
const name = toRef(user, 'name')
// 所有属性响应式解构
const { age } = toRefs(user)
</script>
6. 生命周期
Vue 3 生命周期分为「创建 → 挂载 → 更新 → 销毁」四个阶段,组合式 API 需导入对应钩子函数,最常用的是 onMounted(页面挂载完成):
vue
<script setup>
import { onMounted, onUpdated, onUnmounted } from 'vue'
// 页面挂载完成(DOM 已生成)
onMounted(() => {
console.log('页面挂载完成')
})
// 数据更新触发
onUpdated(() => {
console.log('数据更新了')
})
// 组件销毁前
onUnmounted(() => {
console.log('组件即将销毁')
})
</script>
7. Hook:逻辑复用
Hook 是「可复用的逻辑函数」,将组件中重复的逻辑抽离,让组件更简洁:
步骤1:创建 Hook 文件(useCount.js)
js
// src/hooks/useCount.js
import { ref } from 'vue'
export function useCount() {
// 可复用的响应式数据
const count = ref(0)
// 可复用的方法
const add = () => count.value++
const minus = () => count.value--
// 返回需要暴露的内容
return { count, add, minus }
}
步骤2:组件中使用 Hook
vue
<script setup>
import { useCount } from './hooks/useCount'
// 复用计数逻辑
const { count, add, minus } = useCount()
</script>
<template>
<div>{{ count }}</div>
<button @click="add">+1</button>
<button @click="minus">-1</button>
</template>
五、实用工具
1. 路径别名:@
Vue 中 @ 代表 src 目录,简化路径导入:
js
// 导入 src/components/Child.vue
import Child from '@/components/Child.vue'
2. Vue 开发者工具
浏览器安装 Vue Devtools 插件,可实时调试组件、响应式数据、生命周期,是 Vue 开发必备工具。
六、总结
Vue 3 的核心是「组合式 API + 响应式」,掌握以下关键点即可应对大部分开发场景:
<script setup>是组合式 API 的核心语法糖,脱离this编写逻辑;ref通用响应式,reactive专用于引用类型,按需选择;- 组件通信:Props 父传子,
defineExpose父取子; computed做数据加工,watch/watchEffect监听数据变化;- Hook 实现逻辑复用,让代码更简洁。
Vue 3 语法灵活且高效,结合 TypeScript 可进一步提升代码健壮性,建议多动手实践,将知识点落地到项目中,加深理解。