文章目录
-
- [一.setup:组合式 API 的 "舞台"](#一.setup:组合式 API 的 “舞台”)
- 二.响应式函数
-
- [1. ref:定义基本类型 / 对象的响应式](#1. ref:定义基本类型 / 对象的响应式)
- [2. reactive:用reactive(对象/数组)定义,直接操作对象属性即可(无需.value)](#2. reactive:用reactive(对象/数组)定义,直接操作对象属性即可(无需.value))
- 三、计算属性:computed
- [四、监视函数:watch 与 watchEffect](#四、监视函数:watch 与 watchEffect)
- [五.组件通信:props 与 emit](#五.组件通信:props 与 emit)
Vue3学习前先提出一个问题:什么是响应式对象?
响应式对象(Reactive Object) 是一种具备 "状态感知与自动反馈" 能力的数据载体,其核心特性是:当对象内部的状态(如属性值)发生变化时,依赖该状态的代码(如视图、计算逻辑)会自动触发更新,无需手动调用刷新逻辑
一.setup:组合式 API 的 "舞台"
作用:Vue3 组件的入口,所有组合式 API(数据、方法、计算属性等)都写在这里。
返回值:
返回对象:对象里的属性 / 方法可直接在模板中使用(常用)。
返回渲染函数:自定义模板内容(了解即可)。
注意事项:
尽量不与 Vue2 配置(data、methods 等)混用;若混用,Vue2 配置能访问 setup,setup 不能访问 Vue2 配置,重名时 setup 优先。
不能是 async 函数(返回 Promise,模板无法读取属性)。
二.响应式函数
响应式函数:ref 与 reactive
实现 "数据变,视图 / 逻辑自动更新" 的核心函数。

1. ref:定义基本类型 / 对象的响应式

注意:
在模板里不用.value
在实例中想要获得ref()中的数据需要变量名.value,是为了获取ref()里真正的值
2. reactive:用reactive(对象/数组)定义,直接操作对象属性即可(无需.value)
html
<template>
<h2>姓名:{{ person.name }}</h2>
<h2>工资:{{ person.job.j1.salary }}</h2>
<button @click="changeSalary">涨工资</button>
</template>
<script>
import { reactive } from 'vue'
export default {
setup() {
// 定义响应式对象
let person = reactive({
name: '张三',
age: 18,
job: { j1: { salary: 20 } }
})
// 直接修改属性
function changeSalary() {
person.job.j1.salary = 30
}
return { person, changeSalary }
}
}
</script>

三、计算属性:computed
作用:依赖数据变化时,自动计算新值(与 Vue2 功能一致)。
用法:引入computed,支持 "简写(仅读)" 和 "完整写(可读可写)"。

四、监视函数:watch 与 watchEffect
- watch函数
用法:watch(监视目标, 回调函数, 配置项),配置项支持immediate(立即执行)、deep(深度监视)


使用ref定义对象时,person.value 监视的不在是ref里面的数据,而是ref里面求助reactive所定义的那个数据

此种写法开启了ref的深度监视,也可实现获取person嵌套对象的响应式
- watchEffect函数

html
<script>
import { ref, watchEffect } from 'vue'
export default {
setup() {
let sum = ref(0)
let msg = ref('hello')
// 用到sum和msg,这两个变量变化时都会触发回调
watchEffect(() => {
console.log('sum或msg变了:', sum.value, msg.value)
})
return { sum, msg }
}
}
</script>
watchEffect函数,直接写回调,不写监视对象
回调函数中用到谁就监视谁,谁变了就会重新走
五.组件通信:props 与 emit
setup参数:props context 第一个参数从外传来的参数第二个参数上下文对象
需要用props接收
示例:props:['msg','school']

- props:父传子
用法:setup第一个参数接收props,组件需声明接收的属性。
代码示例(子组件):
html
<script>
export default {
props: ['msg', 'school'], // 声明接收
setup(props) {
console.log('父传过来的msg:', props.msg)
return {}
}
}
</script>
- emit:子传父(自定义事件)
用法:setup第二个参数context中的emit方法触发事件,父组件通过@事件名监听
代码示例:
html
<!-- 子组件 -->
<script>
export default {
setup(props, context) {
function sendData() {
// 触发自定义事件,并传参
context.emit('hello', 666)
}
return { sendData }
}
}
</script>
<!-- 父组件 -->
<template>
<子组件 @hello="handleHello"></子组件>
</template>
<script>
export default {
methods: {
handleHello(val) {
console.log('子组件传过来的参数:', val) // 输出666
}
}
}
</script>
调用 context.emit('hello', 666) 时,第一个参数 'hello' 是自定义事件的名称,需与父组件绑定的事件名一致;第二个参数 666 是传递给父组件的参数。
简单来说,这是 Vue 框架内置的自定义事件通信机制,context.emit 是子组件主动触发该机制的 "开关",从而让父组件的事件处理逻辑得以执行。