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

Vue3.0组合式API:computed计算属性、watch监听器、watchEffect高级监听器

 Vue3.0组合式API系列文章:

《Vue3.0组合式API:setup()函数》

《Vue3.0组合式API:使用reactive()、ref()创建响应式代理对象》

《Vue3.0组合式API:computed计算属性、watch监听器、watchEffect高级监听器》

《Vue3.0组合式API:使用defineProps()实现父组件向子组件传递数据》

《Vue3.0组合式API:使用defineEmits()实现子组件向父组件传递数据》

《Vue3.0组合式API:生命周期钩子函数》

《Vue3.0组合式API:依赖注入provide和inject实现跨层组件的通信》

《Vue3.0组合式API:使用ref获取DOM元素》

1、computed() 计算属性

在模板中绑定表达式只能用于简单的运算。如果运算比较复杂,可以使用 Vue.js 提供的计算属性,通过计算属性可以处理比较复杂的逻辑。

1.1 计算属性的应用

通过计算属性可以实现各种复杂的逻辑,包括运算、函数调用等,只要最后返回一个计算结果就可以。当计算属性依赖的数据发生变化时,计算属性的值会自动更新,所有依赖该计算属性的数据绑定也会同步进行更新。

【实例】使用 computed 计算属性,实现每个单词首字母大写。

<template><p>原字符串:{{ data }}</p><p>新字符串:{{ newData }}</p>
</template><script setup>
//导入函数
import { ref, computed } from 'vue';//创建一个响应式代理对象
const data = ref('my heart will go on');//计算方法:实现首字母大写
const newData = computed(() => {let arr = data.value.split(' '); //注意:使用响应式对象的.value属性,获取内部值for (let i = 0; i < arr.length; i++) {arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].substr(1).toLowerCase();}return arr.join(' ');
});</script>

执行结果:

2.2 计算属性的 getter 和 setter

每一个计算属性都包含一个 getter 和一个 setter。getter 只要用来读取值,而 setter 主要用来设置值。getter 主要用来读取值,而 setter 主要用来设置值。当手动更新计算属性的值时,就会触发 setter,执行一些自定义的操作。

【实例】使用 计算属性的 getter 和 setter,重新设置人物姓名。

<template><p>人物名称:{{ person.fullname }}</p>
</template><script setup>
//导入函数
import { reactive, computed } from 'vue';//创建一个响应式代理对象
const person = reactive({firstName: 'Jim',lastName: 'Carrey'
});// 计算属性 - 简写
// person.fullName = computed(() => {
//   return `${person.firstName} ${person.lastName}`
// })//计算属性的 getter 和 setter
person.fullname = computed({get() {return `${person.firstName} ${person.lastName}`},set(value) {const arr = value.split(' ');person.firstName = arr[0]person.lastName = arr[1]}
});//重新设置人物名称
person.fullname = 'Will Smith';</script>

执行结果:

1.3 methods 与 computed 的区别

问:Vue 中的 methods 方法与 computed 计算属性有什么区别?

答:主要区别是 methods 方法会实时计算,而 computed 计算属性是使用缓存数据。

将相同的操作定义为一个方法,或者定义为一个计算属性,两种方式的结果完全相同。那么为什么还需要计算属性呢?因为计算属性是基于它们的依赖进行缓存的。当页面重新渲染时,如果依赖的数据未发生改变,使用计算属性获取的值就是一直是缓存值。只有依赖的数据发生改变时才会重新获取值。如果使用的是方法,在页面重新渲染时,方法中的函数总会被重新调用。

详情请浏览本博客的文章:《Vue中的methods方法与computed计算属性的区别》

2、watch() 监听器

watch() 方法相当于 Vue 根实例选项对象中的 watch 选项。该方法用于监听特定的数据,并在回调函数中应用。当被监听的数据发生变化时,才会调用回调函数。

2.1 监听 ref 响应式对象

watch() 方法可以接收两个参数。如果使用该方法监听的是一个 ref 对象,那么第一个参数需要监听的 ref 对象,第二个参数是当监听的数据发生变化时触发的回调函数。

【实例】使用 watch() 方法监听一个 ref 响应式对象,实现“米”和“厘米”单元的换算结果。

<template>请输入米数:<input type="text" size="6" v-model="data" /><p>换算结果:{{ result }}</p>
</template><script setup>
//导入函数
import { ref, watch } from 'vue';//创建一个 ref 响应式代理对象
const data = ref(0);//换算结果变量
const result = ref('');//watch监听器
watch(data, (newValue, oldValue) => {console.log("新值", newValue);console.log("旧值", oldValue);result.value = `${data.value} 米 = ${data.value * 100} 厘米`;
});</script>

执行结果:

2.2 监听 reactive 响应式对象

如果 watch() 方法监听的是一个 reactive 对象中的某个属性,那么第一个参数需要使用返回该属性的函数的方式。

watch() 方法的两个额外参数:

1、immediate:是否立即执行。

2、deep:是否深度监听。

注意:

如果要监听的属性值是一个对象,要想监听对象内部值的变化,需要在监听属性的选项参数中设置 deep 选项的值为 true(开启深度监听)。

【实例2】使用 watch() 方法监听一个 reactive 响应式对象中的某个属性,输出属性的原值和新值。

<template><p>商品名称:{{ product.name }}</p><p>{{ product.remark }}</p>
</template><script setup>
//导入函数
import { reactive, watch } from 'vue';//创建一个 reactive 响应式代理对象
const product = reactive({name: '华为手机',price: 6999,remark: ''
});//watch监听器
watch(() => product.price, (newValue, oldValue) => {product.remark = `原价格:${oldValue}元,新价格:${newValue}元`;
},//两个额外参数(非必填){immediate: false,  //关闭:立即监听;默认关闭deep: true         //开启:深度监听;如果监听对象是 reactive() 响应式对象,则默认自动开启});//修改属性值
product.price = 3999;</script>

执行结果:

2.3 监听多个属性

监听属性通常用来实现数据之间的换算,如长度单位之间的换算、速度单位之间的换算、汇率之间的换算等。

【实例】使用 watch() 方法监听多个属性,实现速度单位之间的换算。

<template><p><label for="meter">米/秒:</label><input id="meter" type="number" v-model="meter"></p><p><label for="kilometer">千米/小时:</label><input id="kilometer" type="number" v-model="kilometer"></p>{{ meter }}米/秒={{ kilometer }}千米/小时
</template><script setup>
//导入函数
import { ref, watch } from 'vue';//创建两个 ref 响应式代理对象
const meter = ref(0);
const kilometer = ref(0);//watch监听器:监听多个属性
watch([meter, kilometer],([newMeter, newKilometer], [oldMeter, oldKilometer]) => {if (newMeter != oldMeter) {kilometer.value = newMeter * 3600 / 1000;}if (newKilometer != oldKilometer) {meter.value = newKilometer * 1000 / 3600;}}
);</script>

执行结果:

3、watchEffect() 高级监听器

3.1 watchEffect() 的使用

watchEffect() 方法用来监听数据的变化,类似于 Vue 2.x 中的 watch 选项。该方法接收一个函数作为参数,它会立即执行一次,同时会跟踪函数里面用到的所有响应式状态,当状态发生变化时会重新运行该函数。

【实例】使用 watchEffect() 方法监听数据,实现“米”和“厘米”单元的换算结果。

<template>请输入米数:<input type="text" size="6" v-model="data" /><p>换算结果:{{ result }}</p>
</template><script setup>
//导入函数
import { ref, watchEffect } from 'vue';//创建一个 ref 响应式代理对象
const data = ref(0);//换算结果变量
const result = ref('');//watch监听器
watchEffect(() => {result.value = `${data.value} 米 = ${data.value * 100} 厘米`;
});</script>

执行结果:

3.2 watch 和 watchEffect 的区别

watch 和 watchEffect 是 Vue 3.0 中新增的两个响应式 API,用于监听数据的变化。watch 适用于需要获取新值和旧值,或者需要懒执行的场景,而 watchEffect 适用于需要监听多个数据源,并且需要立即执行的场景。它们之间的区别如下:

  1. watch 是监听单个数据源,可以设置 immediate 和 deep 选项,可以获取新值和旧值;watchEffect 则是监听一组数据源,不能设置 immediate 和 deep 选项,不能获取新值和旧值。
  2. watch 是懒执行的,只有在数据变化时才会执行回调函数,而 watchEffect 则是立即执行的,不管数据是否变化。
  3. watch 可以监听计算属性,而 watchEffect 不能监听计算属性。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C++ 常用设计模式
  • 有源滤波器UAF42
  • Golang协程泄漏定位和排查
  • 项目小总结
  • 在CentOS上搭建NFS服务器
  • rtmp推流
  • yolov8多任务模型-目标检测+车道线检测+可行驶区域检测-yolo多检测头代码+教程
  • 硬件工程师笔试面试——变压器
  • OpenAl o1论文:Let’s Verify Step by Step 快速解读
  • 模版进阶(template)
  • MySQL行转列
  • 聊聊Netty对于内存方面的优化
  • 使用 Sahi 实现 Web 自动化测试
  • HeterGCL-Graph Contrastive Learning Framework on Heterophilic Graph
  • 魅族20机型 M2381“工程固件”作用分析以及写入步骤
  • 【RocksDB】TransactionDB源码分析
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • FastReport在线报表设计器工作原理
  • Golang-长连接-状态推送
  • gulp 教程
  • Linux CTF 逆向入门
  • Lsb图片隐写
  • Magento 1.x 中文订单打印乱码
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • nodejs调试方法
  • Vultr 教程目录
  • webpack4 一点通
  • 番外篇1:在Windows环境下安装JDK
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 一起参Ember.js讨论、问答社区。
  • linux 淘宝开源监控工具tsar
  • ​数据链路层——流量控制可靠传输机制 ​
  • ‌‌雅诗兰黛、‌‌兰蔻等美妆大品牌的营销策略是什么?
  • ###STL(标准模板库)
  • #android不同版本废弃api,新api。
  • #java学习笔记(面向对象)----(未完结)
  • #pragma once
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (12)目标检测_SSD基于pytorch搭建代码
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (C语言)fgets与fputs函数详解
  • (二)延时任务篇——通过redis的key监听,实现延迟任务实战
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (五)MySQL的备份及恢复
  • (一) 初入MySQL 【认识和部署】
  • . NET自动找可写目录
  • ... 是什么 ?... 有什么用处?
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息