后端前行Vue之路(三):计算属性和监视属性

1.概述

书接上回,我们讲述了《后端前行Vue之路(二):模版语法之插值与指令》谈到了Vue的模板语法很强大,支持复杂表达式,如下:

<div id="example">{{ message.split('').reverse().join('') }}
</div>

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。在上面代码示例中,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 message 的翻转字符串。当你想要在模板中的多处包含此翻转字符串时,就会更加难以处理。

Vue提供了**计算属性(Computed Properties)和监视属性(Watch Properties)**都是用于响应数据变化的方式,可以解决模版中复杂表达式场景,使得代码逻辑更加整洁明了和可维护。

2.计算属性Computed

定义方式: 计算属性是通过computed选项来定义的,它接受一个对象,对象的每个键都是计算属性的名称,对应的值是一个函数,用于计算属性的值。如上面的翻转字符串复杂表达式可用计算属性完成如下:

<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>计算属性</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器--><div id="root"><h3>反转的message:{{reversedMessage}}</h3></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({el:'#root',data:{message: "hello world"},computed:{reversedMessage() {return this.message.split('').reverse().join('')}}})</script>
</html>

你可以打开浏览器的控制台,自行修改例子中的 vm。vm.reversedMessage 的值始终取决于 vm.message 的值。

你可以像绑定普通 property 一样在模板中绑定计算属性。Vue 知道 vm.reversedMessage 依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新

你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果:

<h3>反转的message:{{reversedMessage()}}</h3>
// 在组件中
methods: {reversedMessage() {return this.message.split('').reverse().join('')}
}

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:

computed: {now() {return Date.now()}
}

相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

上面展示都是计算属性的简写模式即只有getter方法进行读取属性,但是计算属性也是可以修改的,这时候就需要通过setter函数去响应修改了,下面来看看完整版的写法:通过姓和名组装得到计算属性:fullName:

<script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',data:{firstName:'张',lastName:'三',},computed:{fullName:{//get有什么作用?当有人读取fullName时,get就会被调用,且返回值就作为fullName的值//get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。get(){console.log('get被调用了')// console.log(this) //此处的this是vmreturn this.firstName + '-' + this.lastName},//set什么时候调用? 当fullName被修改时。set(value){console.log('set',value)const arr = value.split('-')this.firstName = arr[0]this.lastName = arr[1]}}}})</script>

项目推荐:基于SpringBoot2.x、SpringCloud和SpringCloudAlibaba企业级系统架构底层框架封装,解决业务开发时常见的非功能性需求,防止重复造轮子,方便业务快速开发和企业技术栈框架统一管理。引入组件化的思想实现高内聚低耦合并且高度可配置化,做到可插拔。严格控制包依赖和统一版本管理,做到最少化依赖。注重代码规范和注释,非常适合个人学习和企业使用

Github地址:https://github.com/plasticene/plasticene-boot-starter-parent

Gitee地址:https://gitee.com/plasticene3/plasticene-boot-starter-parent

微信公众号Shepherd进阶笔记

交流探讨qun:Shepherd_126

3.监视属性Watch

定义方式: 监视属性是通过watch选项来定义的,它接受一个对象,对象的每个键都是要监视的数据属性的名称,对应的值是一个函数,用于在数据变化时执行自定义的操作。通过监视属性完成上面生成全名:

var vm = new Vue({el: '#demo',data: {firstName: 'Foo',lastName: 'Bar',fullName: 'Foo Bar'},watch: {firstName: function (val) {this.fullName = val + ' ' + this.lastName},lastName: function (val) {this.fullName = this.firstName + ' ' + val}}
})

来看看和计算属性对比,计算属性更加简洁。

computed:{reversedMessage() {return this.message.split('').reverse().join('')}}

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。还是上面生成全名的示例,只是现在要求输入姓氏之后1s中才能生成全名:

<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>姓名案例_watch实现</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- computed和watch之间的区别:1.computed能完成的功能,watch都可以完成。2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。两个重要的小原则:1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。--><!-- 准备好一个容器--><div id="root">姓:<input type="text" v-model="firstName"> <br/><br/>名:<input type="text" v-model="lastName"> <br/><br/>全名:<span>{{fullName}}</span> <br/><br/></div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',data:{firstName:'张',lastName:'三',fullName:'张-三'},watch:{firstName(val){// 定时器setTimeout(()=>{console.log(this)this.fullName = val + '-' + this.lastName},1000);},lastName(val){this.fullName = this.firstName + '-' + val}}})</script>
</html>

在这个示例中,使用 watch 选项允许我们执行异步操作,计算属性无法做到的。

深度监视

<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>天气案例_深度监视</title><!-- 引入Vue --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 深度监视:(1).Vue中的watch默认不监测对象内部值的改变(一层)。(2).配置deep:true可以监测对象内部值改变(多层)。备注:(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!(2).使用watch时根据数据的具体结构,决定是否采用深度监视。--><!-- 准备好一个容器--><div id="root"><h2>今天天气很{{info}}</h2><button @click="changeWeather">切换天气</button><hr/><h3>a的值是:{{numbers.a}}</h3><button @click="numbers.a++">点我让a+1</button><h3>b的值是:{{numbers.b}}</h3><button @click="numbers.b++">点我让b+1</button><button @click="numbers = {a:666,b:888}">彻底替换掉numbers</button>{{numbers.c.d.e}}</div></body><script type="text/javascript">Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。const vm = new Vue({el:'#root',data:{isHot:true,numbers:{a:1,b:1,c:{d:{e:100}}}},computed:{info(){return this.isHot ? '炎热' : '凉爽'}},methods: {changeWeather(){this.isHot = !this.isHot}},watch:{isHot:{// immediate:true, //初始化时让handler调用一下//handler什么时候调用?当isHot发生改变时。handler(newValue,oldValue){console.log('isHot被修改了',newValue,oldValue)}},//监视多级结构中某个属性的变化/* 'numbers.a':{handler(){console.log('a被改变了')}} *///监视多级结构中所有属性的变化numbers:{deep:true,handler(){console.log('numbers改变了')}}}})</script>
</html>

4.总结

计算属性和监视属性:

  1. 共同点:
    • 都用于响应数据变化。
    • 都是Vue实例的选项,可以在组件定义时使用。
    • 都可以监视数据变化,并在数据变化时执行自定义的操作。
  2. 区别:
    • 计算属性是基于依赖的缓存属性,只有在相关依赖发生改变时才会重新求值,而监视属性则没有缓存机制,每次数据变化都会触发相应的操作。
    • 计算属性通常用于处理需要根据其他数据动态计算得出的属性值,而监视属性用于执行异步或开销较大的操作,或者在数据变化时执行其他自定义的操作。

总之,计算属性和监视属性都是Vue提供的响应式数据处理机制,您可以根据具体的需求选择使用其中之一或者两者结合使用。

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

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

相关文章

Supervised Fine-tuning in turn Improves Visual Foundation Models

简介 从NLP中的监督微调&#xff08;Supervised Fine-tuning&#xff09;获得的灵感&#xff0c;本文探索了细粒度SFT在预训练后增强视觉基础模型潜力。本文提出了一种二阶段方法ViSFT释放视觉基础模型细粒度知识。具体地&#xff0c;通过一些域内任务执行视觉联合学习增强视觉…

编程实战:自己编写HTTP服务器(系列9:上传文件)

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 本系列的源码位于httpd目录下…

Java实现两数相除

题意 给你两个整数&#xff0c;被除数 dividend 和除数 divisor。将两数相除&#xff0c;要求不使用乘法、除法和取余运算。 整数除法应该向零截断&#xff0c;也就是截去&#xff08;truncate&#xff09;其小数部分。例如&#xff0c;8.345 将被截断为 8 &#xff0c;-2.7335…

用DasViewer浏览模型时可以移动模型的中心点吗?

按住鼠标中键&#xff0c;就正常平移模型了。 DasViewer是由大势智慧自主研发的免费的实景三维模型浏览器,采用多细节层次模型逐步自适应加载技术,让用户在极低的电脑配置下,也能流畅的加载较大规模实景三维模型,提供方便快捷的数据浏览操作。 DasViewer下载地址&#xff1a;…

leetcode 热题 100(部分)C/C++

leetcode 热题 100 双指针 盛最多水的容器 【mid】【双指针】 思路&#xff1a; 好久没写代码sb了&#xff0c;加上之前写的双指针并不多&#xff0c;以及有点思维定势了。我对双指针比较刻板的印象一直是两层for循环i&#xff0c;j&#xff0c;初始时i,j都位于左界附近&…

SAM Self-Attention based Deep Learning Method

一、Why(Research Background) 网络流量分类根据协议(如超文本传输协议或域名系统)或应用程序(如脸书或Gmail)对流量类别进行分类。其准确性是一些网络管理任务(如服务质量控制、异常检测等)的关键基础。为了进一步提高流量分类的准确性,最近的研究引入了基于深度学习的方法…

Open CASCADE学习|刚体( TopoDS_Shape)按某种轨迹运动,停在指定位置上

今天实现如下功能&#xff1a;刚体做做螺旋运动&#xff0c;轨迹已知&#xff0c;求刚体在每个位置上的所占据的空间&#xff0c;就是把刚体从初始位置变换到该位置。 这里的刚体是一个砂轮截面&#xff0c;螺旋运动轨迹由B样条曲线拟合&#xff0c;通过Frenet标架确定运动轨迹…

datalist是什么,有什么作用?

<datalist>标签用于定义一个预定义选项列表&#xff0c;它可以与文本输入框&#xff08;<input type"text">&#xff09;一起使用&#xff0c;提供一组可选的值供用户选择或输入。<datalist>标签中的选项可以通过<option>标签来定义。 <…

多线程(29)Semaphore

Semaphore&#xff08;信号量&#xff09;是一种常用的并发控制技术&#xff0c;用于管理对一组资源的访问控制。信号量的核心是一个计数器&#xff0c;表示可用资源的数量。计数器的值可以初始化为任意值&#xff0c;如果初始化为1&#xff0c;则成为一个互斥锁&#xff08;Mu…

iOS使用CoreML运用小型深度神经网络架构对图像进行解析

查找一个图片选择器 我用的是ImagePicker 项目有点老了&#xff0c;需要做一些改造&#xff0c;下面是新的仓库 platform :ios, 16.0use_frameworks!target learnings dosource https://github.com/CocoaPods/Specs.gitpod ImagePicker, :git > https://github.com/KevinS…

Python之Opencv进阶教程(1):图片模糊

1、Opencv提供了多种模糊图片的方法 加载原始未经模糊处理的图片 import cv2 as cvimg cv.imread(../Resources/Photos/girl.jpg) cv.imshow(girl, img)1.1 平均值 关键代码 # Averaging 平均值 average cv.blur(img, (3, 3)) cv.imshow(Average Blur, average)实现效果 1.2…

STM32F407 FSMC并口读取AD7606

先贴一下最终效果图.这个是AD7606并口读取数据一个周期后的数据结果. 原始波形用示波器看是很平滑的. AD7606不知为何就会出现干扰, 我猜测可能是数字信号干扰导致的. 因为干扰的波形很有规律. 这种现象基本上可以排除是程序问题. 应该是干扰或者数字信号干扰,或者是数字和模拟…

基于Spring Boot的餐厅点餐系统

基于Spring Boot的餐厅点餐系统 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;Maven3.3.9 部分系统展示 管理员登录界面 用户注册登录界面 …

​如何使用ArcGIS Pro进行洪水淹没分析

洪水淹没分析是一种常见的水文地理信息系统应用&#xff0c;用于模拟和预测洪水事件中可能受到淹没影响的地区&#xff0c;这里为大家介绍一下ArcGIS Pro进行洪水淹没分析的方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的DEM数据&…

Python学习笔记-Flask接收post请求数据并存储数据库

1.引包 from flask import Flask, request, jsonify from flask_sqlalchemy import SQLAlchemy 2.配置连接,替换为自己的MySQL 数据库的实际用户名、密码和数据库名 app Flask(__name__) #创建应用实列 app.config[SQLALCHEMY_DATABASE_URI] mysqlpymysql://ro…

优化 Nginx 处理 504 Gateway Timeout 错误

简介 504 Gateway Timeout 错误表示 Nginx 在指定的时间内没有从上游服务器收到响应。这可能是由于上游服务器处理时间过长或网络连接问题造成的。 调整 Nginx 参数 为了解决 504 错误&#xff0c;可以调整以下 Nginx 参数&#xff1a; **proxy_read_timeout&#xff1a;**指…

如何判断驱动中probe是否执行

在我们调试驱动程序的时候需要查看probe函数是否执行&#xff0c;我们只需要在其probe函数写一个printk函数即可&#xff0c;在驱动和设备匹配之后就会执行这个probe里面的打印函数 但是前提我们需要降低内核的打印级别&#xff0c;否则是看不到的&#xff0c;我们可以降到最低…

mac电脑maven配置环境变量

1、下载maven https://maven.apache.org 2、配置环境变量 vim .bash_profile JAVA_HOME/Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home PATH$JAVA_HOME/bin:$PATH export JAVA_HOME export PATH#maven export MAVEN_HOME/Users/haines/desktop/work/java/a…

鸿蒙OS开发实例:【应用事件打点】

简介 传统的日志系统里汇聚了整个设备上所有程序运行的过程流水日志&#xff0c;难以识别其中的关键信息。因此&#xff0c;应用开发者需要一种数据打点机制&#xff0c;用来评估如访问数、日活、用户操作习惯以及影响用户使用的关键因素等关键信息。 HiAppEvent是在系统层面…

适用于 Linux 的 Windows 子系统安装初体验

1、简述 Windows Subsystem for Linux (WSL) 是 Windows 的一项功能&#xff0c;允许您在 Windows 计算机上运行 Linux 环境&#xff0c;而无需单独的虚拟机或双重启动。 WSL 旨在为想要同时使用 Windows 和 Linux 的开发人员提供无缝且高效的体验。 使用 WSL 安装和运行各种 L…