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

2024-04-03 20:20

本文主要是介绍后端前行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提供的响应式数据处理机制,您可以根据具体的需求选择使用其中之一或者两者结合使用。

这篇关于后端前行Vue之路(三):计算属性和监视属性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/873882

相关文章

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

Java如何通过反射机制获取数据类对象的属性及方法

《Java如何通过反射机制获取数据类对象的属性及方法》文章介绍了如何使用Java反射机制获取类对象的所有属性及其对应的get、set方法,以及如何通过反射机制实现类对象的实例化,感兴趣的朋友跟随小编一... 目录一、通过反射机制获取类对象的所有属性以及相应的get、set方法1.遍历类对象的所有属性2.获取

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

VUE动态绑定class类的三种常用方式及适用场景详解

《VUE动态绑定class类的三种常用方式及适用场景详解》文章介绍了在实际开发中动态绑定class的三种常见情况及其解决方案,包括根据不同的返回值渲染不同的class样式、给模块添加基础样式以及根据设... 目录前言1.动态选择class样式(对象添加:情景一)2.动态添加一个class样式(字符串添加:情

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用

如何用Java结合经纬度位置计算目标点的日出日落时间详解

《如何用Java结合经纬度位置计算目标点的日出日落时间详解》这篇文章主详细讲解了如何基于目标点的经纬度计算日出日落时间,提供了在线API和Java库两种计算方法,并通过实际案例展示了其应用,需要的朋友... 目录前言一、应用示例1、天安门升旗时间2、湖南省日出日落信息二、Java日出日落计算1、在线API2

使用Vue.js报错:ReferenceError: “Vue is not defined“ 的原因与解决方案

《使用Vue.js报错:ReferenceError:“Vueisnotdefined“的原因与解决方案》在前端开发中,ReferenceError:Vueisnotdefined是一个常见... 目录一、错误描述二、错误成因分析三、解决方案1. 检查 vue.js 的引入方式2. 验证 npm 安装3.

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

python解析HTML并提取span标签中的文本

《python解析HTML并提取span标签中的文本》在网页开发和数据抓取过程中,我们经常需要从HTML页面中提取信息,尤其是span元素中的文本,span标签是一个行内元素,通常用于包装一小段文本或... 目录一、安装相关依赖二、html 页面结构三、使用 BeautifulSoup javascript

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义