当前位置: 首页 > news >正文

【卷起来】VUE3.0教程-05-侦听器

=========各位看官,在开始学习之前,请帮我点个关注和赞吧========== 

🌲 基本示例

计算属性允许我们声明性地计算衍生值。然而在有些情况下,我们需要在状态变化时执行一些“副作用”:例如更改 DOM,或是根据异步操作的结果去修改另一处的状态。

在组合式 API 中,我们可以使用 watch函数在每次响应式状态发生变化时触发回调函数:


<template><p>Ask a yes/no question:<input v-model="question" /></p><p>{{ answer }}</p></template>
<script setup>
import { ref, watch } from 'vue'
const question = ref('')
const answer = ref('Questions usually contain a question mark. ;-)')// 可以直接侦听一个 ref
watch(question, async (newQuestion, oldQuestion) => {if (newQuestion.indexOf('?') > -1) {answer.value = 'Thinking...'try {const res = await fetch('https://yesno.wtf/api')answer.value = (await res.json()).answer} catch (error) {answer.value = 'Error! Could not reach the API. ' + error}}
})</script>

🌲 侦听数据源类型

watch 的第一个参数可以是不同形式的“数据源”:它可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组:


<template><input v-model="x" /><input v-model="y"/></template>
<script setup>
import {ref,watch} from 'vue'
const x = ref(0)
const y = ref(0)// 单个 ref
watch(x, (newX) => {console.log(`x is ${newX}`)
})// getter 函数
watch(// 类似于 Java中的getSum()() => x.value + y.value,// 将sum的值传入函数(sum) => {console.log(`sum of x + y is: ${sum}`)}
)// 多个来源组成的数组
watch([x, () => y.value], ([newX, newY]) => {console.log(`x is ${newX} and y is ${newY}`)
})</script>

注意,你不能直接侦听响应式对象的属性值,例如:

<template><input v-model="obj.count"/>
</template>
<script setup>const obj = reactive({ count: 0 })// 错误,因为 watch() 得到的参数是一个 numberwatch(obj.count, (count) => {console.log(`count is: ${count}`)})</script>

上面代码会报错:A watch source can only be a getter/effect function

这里需要用一个返回该属性的 getter 函数:


const obj = reactive({ count: 0 })// 提供一个 getter 函数
watch(() => obj.count,(count) => {console.log(`count is: ${count}`)}
)

🌲 深层侦听器

直接给 watch() 传入一个响应式对象,会隐式地创建一个深层侦听器——该回调函数在所有嵌套的变更时都会被触发:


<template><input v-model="obj.count"/><input v-model="obj.show"/></template>
<script setup>
import {ref,watch,reactive} from 'vue'const obj = reactive({ count: 0,show:5 })watch(obj, (newValue, oldValue) => {// 在嵌套的属性变更时触发// 注意:`newValue` 此处和 `oldValue` 是相等的// 因为它们是同一个对象!console.log("你修改了obj中的属性,count现在的值:"+obj.count)
})</script>

但是,如果返回一个响应式对象的 getter 函数,只有在返回对象相对应的属性数据时时,才会触发回调:


<template><!-- <input v-model="obj.count"/>0 --><input v-model="mywife.name"/></template>
<script setup>
import {ref,watch,reactive} from 'vue'var mywife = reactive({'name':'西施','age':18})watch(() => mywife.name,() =>{// 仅当state.mywife发生变化的时候触发console.log("你现在的老婆是?"+mywife.name)}
)</script>

我们也可以给上面这个例子显式地加上 deep 选项,强制转成深层侦听器,这样当所有属性发生变化时都可以监听到:


<template><!-- <input v-model="obj.count"/>0 --><input v-model="mywife.name"/><input v-model="mywife.age"/></template>
<script setup>
import {ref,watch,reactive} from 'vue'var mywife = reactive({'name':'西施','age':18})watch(() => mywife.name,() =>{// 仅当mywife.name发生变化的时候触发console.log("你现在的老婆是?"+mywife.name+"她现在"+mywife.age+"岁")},// 深度侦听{deep:true})</script>

🌲 即时回调的侦听器

watch 默认是懒执行的:仅当数据源变化时,才会执行回调。但在某些场景中,我们希望在创建侦听器时,立即执行一遍回调。举例来说,我们想请求一些初始数据,然后在相关状态更改时重新请求数据。

我们可以通过传入 immediate: true 选项来强制侦听器的回调立即执行:

直接修改上一个案例,在里面添加{immediate: true}


<template><!-- <input v-model="obj.count"/>0 --><input v-model="mywife.name"/><input v-model="mywife.age"/></template>
<script setup>
import {ref,watch,reactive} from 'vue'var mywife = reactive({'name':'西施','age':18})watch(() => mywife.name,() =>{// 仅当mywife.name发生变化的时候触发console.log("你现在的老婆是?"+mywife.name+"她现在"+mywife.age+"岁")},// 深度侦听{deep:true},// 即时回调{immediate:true})</script>

🌲 watchEffect()

侦听器的回调使用与源完全相同的响应式状态是很常见的。例如下面的代码,在每当 todoId 的引用发生变化时使用侦听器来加载一个远程资源:

<template><input v-model="todoId"/></template>
<script setup>
import {ref,watch,reactive} from 'vue'const todoId = ref(1)
const data = ref(null)watch(todoId, async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()console.log(data.value)
}, { immediate: true })</script>

特别是注意侦听器是如何两次使用 todoId 的,一次是作为源,另一次是在回调中。

我们可以用 watchEffect函数 来简化上面的代码。watchEffect() 允许我们自动跟踪回调的响应式依赖。上面的侦听器可以重写为:


<template><input v-model="todoId"/></template>
<script setup>
import {ref,watch,watchEffect,reactive} from 'vue'const todoId = ref(1)
const data = ref(null)
watchEffect(async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()console.log(data.value)
})</script>

这个例子中,回调会立即执行,不需要指定 immediate: true。在执行期间,它会自动追踪 todoId.value 作为依赖(和计算属性类似)。每当 todoId.value 变化时,回调会再次执行。有了 watchEffect(),我们不再需要明确传递 todoId 作为源值。

对于这种只有一个依赖项的例子来说,watchEffect() 的好处相对较小。但是对于有多个依赖项的侦听器来说,使用 watchEffect() 可以消除手动维护依赖列表的负担。此外,如果你需要侦听一个嵌套数据结构中的几个属性,watchEffect() 可能会比深度侦听器更有效,因为它将只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 南通网站建设手机版网页
  • HTML5好看的花店商城源码3
  • MySQL—死锁
  • 内网穿透的应用-本地化部署Elasticsearch平替工具OpenObserve并实现无公网IP远程分析数据
  • xilinx通用RAM或者FIFO设计
  • 直播相关01-录制麦克风声音,QT上 .pro 将 linux,mac和windows上配置为三种可以共享,
  • 【阿雄不会写代码】全国职业院校技能大赛GZ036第九套
  • 前端开发的单例设计模式
  • 内网穿透的应用-Deepin系统安装x11vnc实现任意设备无公网IP远程连接Deepin桌面
  • ITK-高斯滤波
  • 【数据结构与算法】——学习笔记
  • liunx io模型多路复用
  • 2024年【甘肃省安全员C证】报名考试及甘肃省安全员C证考试总结
  • MyBatis详解
  • ios签名怎么找靠谱的服务商
  • 【Amaple教程】5. 插件
  • Druid 在有赞的实践
  • es6
  • iOS编译提示和导航提示
  • Mysql数据库的条件查询语句
  • PAT A1092
  • 大主子表关联的性能优化方法
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 普通函数和构造函数的区别
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 微信支付JSAPI,实测!终极方案
  • 温故知新之javascript面向对象
  • 异步
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • Linux权限管理(week1_day5)--技术流ken
  • #Spring-boot高级
  • #如何使用 Qt 5.6 在 Android 上启用 NFC
  • (0)Nginx 功能特性
  • (3) cmake编译多个cpp文件
  • (Qt) 默认QtWidget应用包含什么?
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (差分)胡桃爱原石
  • (二)正点原子I.MX6ULL u-boot移植
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (接上一篇)前端弄一个变量实现点击次数在前端页面实时更新
  • (理论篇)httpmoudle和httphandler一览
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (七)理解angular中的module和injector,即依赖注入
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (一一四)第九章编程练习
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • (转)关于多人操作数据的处理策略
  • (转)重识new
  • *算法训练(leetcode)第三十九天 | 115. 不同的子序列、583. 两个字符串的删除操作、72. 编辑距离
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .Net OpenCVSharp生成灰度图和二值图