Vue3 —— 监听器 (watch/watchEffect) 与 Props 组件通信

哈喽~今天是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 组件开发的基础,快动手多敲几遍。

相关推荐
DarkLONGLOVE21 小时前
快速上手 Pinia!Vue3 极简状态管理使用教程
javascript·vue.js
宸翰1 天前
解决 uni-app App 端 vue-i18n 占位符丢失:封装跨端可用的 tf 格式化方法
前端·vue.js·uni-app
用户2136610035721 天前
VueRouter进阶-动态路由与嵌套路由
前端·vue.js
暴走的小呆2 天前
Vue 2 中 Object 的变化侦测:从 getter/setter 到 Dep、Watcher、Observer
vue.js
英勇无比的消炎药2 天前
TinyVue v-auto-tip: 文本超长自动提示的优雅方案
vue.js
时光足迹2 天前
腾讯云 TRTC UniApp SDK 从入门到上线
前端·vue.js·uni-app
时光足迹2 天前
uni-app 里把加密视频嵌入页面播放?我分析了 4 种方案,只有 1 种接近完美
前端·vue.js·uni-app
时光足迹2 天前
JPush UniApp UTS 插件完全参考手册:API、事件与厂商通道一网打尽
vue.js·ios·uni-app
时光足迹2 天前
极光推送全攻略(下):uni-app 代码实现与 iOS 排查实战
vue.js·ios·uni-app
疯狂的魔鬼2 天前
一个"懂分寸"的文本省略组件是怎样炼成的
前端·vue.js·设计