vue3 教程(中)

侦听器

用于侦听指定变量,当其响应式状态变化时触发回调函数。

watch()

watch() 需明确指定侦听的数据源,并且仅当数据源变化时,才会执行回调,在创建侦听器时,不会执行回调,可以获取到数据源变化前后的值。

  • 第一个参数为“数据源”,可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组
  • 第二个参数为回调函数

侦听–响应式变量 / 计算属性

const x = ref(0)
watch(x, (newX) => {console.log(`x is ${newX}`)
})

侦听–响应式对象

会隐式地创建一个深层侦听器,对象的属性和嵌套属性发生变化时,都会触发回调

const obj = reactive({ count: 0 })
watch(obj, (newValue, oldValue) => {// 此处 `newValue` 和 `oldValue` 是相等的,因为它们是同一个对象!
})

若用getter 函数返回响应式对象 ,则只有在返回不同的对象时,才会触发回调:

watch(() => state.someObject,() => {// 仅当 state.someObject 被替换时触发}
)

通过添加 deep 选项,可以将其强制转成深层侦听器(即当对象的属性和嵌套属性发生变化时触发回调)

watch(() => state.someObject,(newValue, oldValue) => {// 此处 `newValue` 和 `oldValue` 是相等的,除非 state.someObject 被整个替换了},{ deep: true }
)

侦听–对象的属性

方案1:用一个返回该属性的 getter 函数

// 侦听obj对象的count属性
watch(() => obj.count,(count) => {console.log(`count is: ${count}`)}
)

方案2:使用 toRefs

import { ref, toRefs, watch } from "vue";
let obj = ref({ count: 30 });
let { count } = toRefs(obj.value);
watch(count, (newValue, oldValue) => {});

不能直接侦听响应式对象的属性值,因为属性值非响应式

const obj = reactive({ count: 0 })// 错误,因为 watch() 得到的参数是一个 number
watch(obj.count, (count) => {console.log(`count is: ${count}`)
})

侦听-- getter 函数

const x = ref(0)
const y = ref(0)watch(() => x.value + y.value,(sum) => {console.log(`sum of x + y is: ${sum}`)}
)

侦听-- 多个数据源

// 多个来源组成的数组
watch([x, () => y.value], ([newX, newY]) => {console.log(`x is ${newX} and y is ${newY}`)
})

watchEffect()

watchEffect()在创建侦听器时,会立即执行一遍回调,并从中自动分析出依赖的数据源(其响应性依赖关系不那么明确),当数据源发生改变时,再次触发回调。无法获取到数据源变化前的值。

watchEffect(async () => {const response = await fetch(url.value)data.value = await response.json()
})

上例中,在页面创建时会先请求 url.value 接口获得初始数据,并自动追踪 url.value
url.value 变化时,会再次执行回调,访问新的接口获取数据。

改变回调的触发时机

默认情况下,侦听器回调会在 Vue 组件更新之前被调用(在侦听器回调中访问的 DOM 是被 Vue 更新之前的状态)

添加 flush: 'post' 选项可以让侦听器回调在 Vue 组件更新之后再调用,这样就能在侦听器回调中访问被 Vue 更新之后的 DOM 啦!

watch(source, callback, {flush: 'post'
})watchEffect(callback, {flush: 'post'
})

后置刷新的 watchEffect() 可以直接用 watchPostEffect()

import { watchPostEffect } from 'vue'watchPostEffect(() => {/* 在 Vue 更新后执行 */
})

停止侦听器

同步语句创建的侦听器,会在组件卸载时自动停止。
异步回调创建的侦听器,必须手动停止它,以防内存泄漏。

setTimeout(() => {watchEffect(() => {})
}, 100)

手动停止侦听器的方法是调用 watch 或 watchEffect 返回的函数

const unwatch = watchEffect(() => {})
unwatch()

异步创建侦听器的情况很少,如果需要等待一些异步数据,可以使用条件式的侦听逻辑:

// 需要异步请求得到的数据
const data = ref(null)watchEffect(() => {if (data.value) {// 数据加载后执行某些操作...}
})

模板引用 ref

用于直接访问底层 DOM 元素,即 vue2 中的 $refs

  <input ref="input" />
import { ref, onMounted } from 'vue'// 声明一个ref变量来存放该元素的引用,变量名必须和模板里的 ref 属性值相同
const input = ref(null)onMounted(() => {// 页面加载后,输入框自动获得焦点input.value.focus()
})

只可以在组件挂载后才能访问模板引用
若侦听模板引用 ref 的变化,需考虑到其值为 null 的情况:

watchEffect(() => {if (input.value) {input.value.focus()} else {// 此时还未挂载,或此元素已经被卸载(例如通过 v-if 控制)}
})

ref 绑定函数

<input :ref="(el) => { /* 将 el 赋值给一个数据属性或 ref 变量 */ }">
  • 绑定函数需使用 :ref
  • 每次Dom更新时函数都会被调用
  • Dom被卸载时,函数也会被调用一次,此时 el 参数的值是 null

子组件上的 ref

若子组件使用的是选项式 API 或没有使用 <script setup> ,则对子组件的模板引用即子组件的 this,可以直接访问子组件的属性和方法。(但仍推荐用标准的 props 和 emit 接口来实现父子组件交互)

使用了 <script setup> 的子组件是默认私有的:父组件无法访问私有子组件中的任何东西,除非子组件通过 defineExpose 宏显式暴露。

<script setup>
import { ref } from 'vue'const a = 1
const b = ref(2)defineExpose({a,b
})
</script>

父组件通过模板引用获取到的实例类型为 { a: number, b: number } (ref 都会自动解包,和一般的实例一样)。

父子组件

父组件中使用子组件 import

vue3 中导入后就能直接使用,无需像 vue2 中进行注册

<script setup>
import ButtonCounter from './ButtonCounter.vue'
</script>
<template><ButtonCounter />
</template>

子组件接收父组件传入的数据 props

子组件用 defineProps() 接收父组件传入的数据

<script setup>
defineProps(['title'])
</script><template><h4>{{ title }}</h4>
</template>

defineProps() 的参数和 props 选项的值相同

defineProps({title: String,likes: Number
})

搭配 TypeScript 使用类型标注来声明 props

<script setup lang="ts">
defineProps<{title?: stringlikes?: number
}>()
</script>

选项式风格中,props 对象会作为 setup() 函数的第一个参数被传入:

export default {props: ['title'],setup(props) {console.log(props.title)}
}

子组件触发自定义事件 emits

组件触发的事件不会冒泡,父组件只能监听直接子组件触发的事件。

父组件–在引入的子组件上绑定事件

<BlogPost @enlarge-text="postFontSize += 0.1"/>

子组件–用 defineEmits() 声明事件

<button @click="$emit('enlarge-text')">Enlarge text</button>
<script setup>
defineEmits(['enlarge-text']) // 多个事件则为 defineEmits(['inFocus', 'submit'])
</script>

选项式风格中,通过 emits 选项定义组件会抛出的事件,并用 setup() 的第二个参数(上下文对象)访问 emit 函数:

export default {emits: ['enlarge-text'],setup(props, ctx) {ctx.emit('enlarge-text')}
}

事件传参

子组件

<button @click="$emit('increaseBy', 1)"></button>

父组件

<MyButton @increase-by="(n) => count += n" />

<MyButton @increase-by="increaseCount" />
function increaseCount(n) {count.value += n
}

子组件继承样式

vue2 中限定只能有一个根节点,父组件中给子组件添加的样式,都会渲染在子组件的根节点上,如:

<!-- 子组件 -->
<p class="child">你好</p>
<!-- 父组件使用子组件时,添加了新的样式 father -->
<MyComponent class="father" />

最终渲染的效果为:

<p class="child father">你好</p>

vue3 中支持多个根节点,所以需要通过 $attrs 指定具体哪些节点继承父组件添加的样式。

<!-- 子组件:在需要继承样式的元素上,添加  :class="$attrs.class" -->
<p :class="$attrs.class">你好</p>
<span>我是朝阳</span>
<!-- 父组件使用子组件时,添加了新的样式 father -->
<MyComponent class="father" />

最终渲染的效果为:

<p class="father">你好</p>
<span>我是朝阳</span>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/164081.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter 父子组件通信

在Flutter 中父组件调用子组件的方法可以通过GlobalKey实现&#xff0c;而子组件调用父组件方法可以通过回调函数实现。 父组件 class _MyHomePageState extends State<MyHomePage> {final GlobalKey<LoadPencilState> loadPencilKey GlobalKey<LoadPencilSt…

react中虚拟dom,diff,fiber - 初级了解

借鉴&#xff1a; 「React深入」一文吃透虚拟DOM和diff算法 - 掘金 (juejin.cn) 虚拟dom、fiber、渲染dom、dom-diff - 掘金 (juejin.cn) 未阅读源码&#xff0c;了解层面&#xff0c;后续可以深入了解 1.虚拟DOM ①.结构上&#xff1a;虚拟DOM比真实DOM轻很多 ②.操作上&…

主流的低代码平台有哪些?程序员应该如何与低代码相处?

本文主要阐述低代码的概念&#xff0c;介绍目前主流的低代码平台&#xff0c;总结低代码平台的典型特征、存在优势以及未来发展趋势。并站在程序员的角度&#xff0c;分析如何在已经到来的低代码战争中&#xff0c;找到自己的定位&#xff0c;一展所长。 什么是低代码&#xff…

脉冲宽度基础知识简介

脉冲宽度是指脉冲所能达到的最大值所持续的周期时间。脉冲宽度是电子领域中一个重要的概念&#xff0c;它与脉冲重复间隔和占空比等参数密切相关。 脉冲宽度通常用于电信号的测量&#xff0c;可以用来描述脉冲的形状、幅度和宽度等特性。在雷达和电源领域中&#xff0c;脉冲宽度…

Flink 替换 Logstash 解决日志收集丢失问题

在某客户日志数据迁移到火山引擎使用 ELK 生态的案例中&#xff0c;由于客户反馈之前 Logstash 经常发生数据丢失和收集性能较差的使用痛点&#xff0c;我们尝试使用 Flink 替代了传统的 Logstash 来作为日志数据解析、转换以及写入 ElasticSearch 的组件&#xff0c;得到了该客…

实现一个计算机

图片&#xff1a; 实现代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>body {padding: 20px;font-family: Arial;}.calc-wrap {width: 300px;bor…

VL06O报表添加增强字段

业务描述 用户需要在VL06O事务代码下进行批量交货过账&#xff0c;现有的筛选条件不太适用当前公司的业务&#xff0c;需要在报表中新增三个交货单增强字段&#xff0c;方便其筛选&#xff08;选择屏幕没有加&#xff0c;用户在报表里用标准按钮功能自己筛选&#xff09; 效果…

十一 动手学深度学习v2计算机视觉 ——微调

一、网络架构 一个神经网络一般可以分成两块 特征抽取&#xff0c;将原始像素变成容易线性分割的特征。线性分类器来做分类。 二、训练 是一个目标数据集上的正常训练任务&#xff0c; 但使用更强的正则化 使用更小的学习率使用更少的数据迭代 源数据集远远复杂于目标数据集…

蓝桥杯算法双周赛心得——迷宫逃脱(dp)

大家好&#xff0c;我是晴天学长&#xff0c;dp版的来啦&#xff0c;可以是受益匪浅啊&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1) .迷宫逃脱 迷官逃脱[算法赛] 问题描述 在数学王国中&#xff0c;存…

便携式心电图机方案_基于MT6735平台的手持心电图机

便携式心电图机具备体积小、易携带、兼容12导模式的特点&#xff0c;通过工频滤波、基线滤波和肌电滤波等处理&#xff0c;能够获得更精准的心电图谱。该设备可以与医院信息系统(HIS)相连接&#xff0c;实现患者信息的共享。采集的心电数据可以通过无线方式发送到心电判读平台&…

企业建数仓的第一步是选择一个好用的ETL工具

当企业决定建立数据仓库&#xff08;Data Warehouse&#xff09;&#xff0c;第一步就是选择一款优秀的ETL&#xff08;Extract, Transform, Load&#xff09;工具。数据仓库是企业数据管理的核心&#xff0c;它存储、整合并管理各种数据&#xff0c;为商业决策和数据分析提供支…

PC8250(CC-CV控制)5V/8A同步降压恒流恒压软启动带EN功能只需极少外围元件

概述 PC8250是一个同步降压转换器输出电流至8A。它的设计允许操作电源电压范围从9V到42V。外部关闭功能可以通过逻辑电平来控制COMP/EN引脚下降&#xff0c;然后进入待机模式。外部补偿使反馈控制具有良好的线路和负载调节&#xff0c;外部设计灵活。PC8250在CC&#xff08;恒定…

【读懂AUTOSAR规范】PduR 缓存分配(Buffer allocation)

1. 前言 PDU路由器模块支持将I-PDU从一个源总线网关到一个或多个目标总线。与从/到本地模块的传输和接收不同,PDU路由器模块必须同时充当接收器和发射器,并且在某些情况下还提供I-PDU的缓冲。网关需求被有意地分离,以便在不需要网关的情况下高效实现PDU路由器模块。如果PDU…

华三无线控制器WX2540H配合准入做Portal认证

数据通信 - 建设篇 - 无线 第四章 华三无线控制器WX2540H配合准入做Portal认证 数据通信 - 建设篇 - 无线系列文章回顾华三无线控制器WX2540H配合准入做Portal认证前言其他配置优化参考来源系列文章回顾 第一章 华三无线控制器配置本地转发 第二章 华三无线控制器配置802.1X认…

Redis-Day1基础篇(初识Redis, Redis常见命令, Redis的Java客户端)

Redis-Day1基础篇 初识Redis认识NoSQL认识Redis安装Redis启动RedisRedis客户端 Redis命令数据结构介绍通用命令操作命令StringHashListSetSortedSet Redis的Java客户端客户端对比Jedis客户端Jedis快速入门Jedis连接池 SpringDataRedis客户端SpringDataRedis概述SpringDataRedis…

boardmix AI思维导图,一键自动生成思维导图!

在日常学习和工作中&#xff0c;我们常常需要记忆和整理大量的知识点和思维结构。 此时&#xff0c;思维导图的存在就大大方便了我们的工作。与传统的文本笔记不同&#xff0c;思维导图可以结合文字、图像、颜色等多种元素&#xff0c;帮助我们更好地整理和分析知识的关系&…

centos7上用docker部署redis

1. 下载redis镜像 docker pull redis docker images # 查看镜像是否下载成功2. 安装redis容器 2.1 先准备好配置文件redis.conf vi /data/redis/redis.conf写入配置信息&#xff0c;appendonly yes&#xff0c;如果需要给redis配置密码&#xff0c;可以写入requirepass root…

如何选择更快更稳定的存储服务器

如何选择更快更稳定的存储服务器 存储介质&#xff1a;存储服务器的主要存储介质包括固态硬盘&#xff08;SSD&#xff09;和机械硬盘&#xff08;HDD&#xff09;。相比于机械硬盘&#xff0c;固态硬盘具有更高的读写速度和更低的延迟&#xff0c;因此能够提供更快的数据传输…

python安装的记录

python setup.py install --user

(附程序)AD采集中的10种经典软件滤波程序优缺点分析

前言 本次我们学习一下AD采集的一些简单的软件滤波算法并分析优缺点 本篇博客大部分是自己收集和整理&#xff0c;如有侵权请联系我删除。 AD采样点的电压多少有点起伏波动&#xff0c;经运放放大后电压的波动如果超过ADC的分辩率&#xff0c;则显示的值会出现波动。波动如…