哈喽~今天是review Vue3 的一天,啃了监听器(watch/watchEffect) 和组件 Props 通信 这两块内容,整理成笔记方便以后复习,也希望能帮到和我一样在学 Vue3 的朋友们~
一、监听器:watch & watchEffect
监听器主要用来监听数据变化并执行回调,Vue3 里提供了**watch** 和**watchEffect**两种方式,各有侧重~
1.1 watch:显式监听,精准控制
**watch**需要明确指定要监听的数据源,能获取新旧值,灵活性更高。
(1)监听单个 ref 数据
javascript
import { ref, watch } from 'vue'
const msg = ref('')
// 监听单个ref
watch(msg, (newVal, oldVal) => {
console.log('新值:', newVal, '旧值:', oldVal)
})
模板里绑定输入框,输入内容时就能监听到msg的变化:
javascript
<input placeholder="请输入" v-model="msg">
(2)监听多个 ref 数据
可以用数组包裹多个数据源,回调里的**newVal** 和**oldVal**也对应数组形式:
javascript
const name = ref('')
const age = ref('')
// 监听多个ref
watch([name, age], (newVal, oldVal) => {
console.log('姓名/年龄新值:', newVal, '旧值:', oldVal)
})
(3)监听 reactive 对象(自动深度监听)
watch 监听**reactive** 对象时,会自动开启深度监听,无需手动配置**deep:true**
javascript
import { reactive } from 'vue'
const data = reactive({
name:"",
user:{
info:""
}
})
// 监听整个reactive对象
watch(data,(newVal,oldVal)=>{
console.log('reactive对象变化:', newVal, oldVal);
})
(4)监听 reactive 对象的某个属性
如果只关注**reactive** 对象里的某个嵌套属性,需要用函数返回值 的形式指定:
javascript
// 监听data.user.info
watch(()=>data.user.info,(newVal,oldVal)=>{
console.log('用户信息变化:', newVal, oldVal);
})
1.2 watchEffect:隐式监听,自动收集依赖
watchEffect 不需要指定监听源,会自动收集回调里用到的响应式数据,组件挂载时会立即执行一次 (默认**immediate**),适合 "副作用自动收集" 的场景。
基本使用 + 暂停 / 恢复监听
TypeScript
import { ref, watchEffect } from 'vue'
const we = ref('')
// 开启watchEffect监听
const handler = watchEffect(()=>{
console.log("we的值:",we.value);
})
// 暂停监听:handler.pause()
// 恢复监听:handler.resume()
模板里绑定输入框和控制按钮:
TypeScript
<input placeholder="输入" v-model="we">
<button @click="handler.pause">暂停监听</button>
<button @click="handler.resume">恢复监听</button>
二、Props:组件间通信的核心
Props 是父组件向子组件传递数据的方式,核心遵循**单向数据流(**父改子更,子不能直接改父传的 props)。
2.1 Props 基本概念
- 作用:实现父子组件数据通信
- 核心规则:单向数据流 → 子组件只能读取 props,不能直接修改(修改会报警告,也不符合设计原则)
2.2 Props 的定义与校验
在子组件中用**defineProps**定义 props,还能做类型、必填、默认值、自定义校验,让传参更规范~
(1)基础定义(无校验)
TypeScript
// 子组件 11.props.vue
const props = defineProps({
name:{}, // 无校验,接收任意类型
age:{}
})
模板中可以直接使用:
XML
<template>
<div>
姓名:{{ props.name }}
<br>
年龄:{{ props.age }}
</div>
</template>
TypeScript
// App.vue
<script setup lang="ts">
import { ref } from 'vue';
import Props from './study_tree/11.props.vue';
const name = ref('');
</script>
<template>
<div>
父组件
<div>
子组件
<Props name="xxx" age="18"></Props>
</div>
</div>
</template>
(2)完整校验(类型 / 必填 / 默认值 / 自定义)
TypeScript
// 子组件 props1.vue
const props = defineProps({
// 必传 + 字符串类型
name:{
required:true, // 注意:原代码里写的require是笔误,正确是required!
type:String
},
// 数字类型 + 默认值
age:{
type:Number,
default:18
},
// 布尔类型
isMall:{
type:Boolean
},
// 复杂类型(对象)默认值:必须用函数返回
user:{
type:Object,
default:()=>({name:'默认用户',age:18})
},
// 自定义校验规则
status:{
type:String,
validator:(value:string)=>{
// 只允许success/warning/danger
return ['success','warning','danger'].includes(value)
}
}
})
2.3 父组件传参示例
父组件通过v-bind(简写:)传递数据给子组件,普通字符串可以直接传,数字 / 对象 / 布尔等要加 : :
TypeScript
<!-- App.vue 父组件 -->
<script setup lang="ts">
import { ref } from 'vue';
import Props1 from './study_tree/props1.vue';
const user = {
name:'张三',
age:20
}
</script>
<template>
<div>
父组件
<div>
<Props1
name="xxx"
:age="30" <!-- 数字类型加: -->
:user="user" <!-- 对象类型加: -->
status="success"
></Props1>
</div>
</div>
</template>
三、今日学习总结
1. 监听器
watch:显式指定监听源,能拿新旧值,适合精准监听;监听 reactive 对象自动深度监听,监听嵌套属性用函数返回值。watchEffect:自动收集依赖,立即执行,适合副作用场景,支持暂停 / 恢复。
2. props
- 核心:单向数据流,父传子,子不能直接改 props。
- 进阶:通过**
defineProps**做类型校验、必填、默认值、自定义校验,让组件传参更规范。
这些都是 Vue3 组件开发的基础,快动手多敲几遍。