我自己很笨,学习编程也是一点一点啃,总是把在别人看起来很简单的一个问题,自己都要反复琢磨好多遍,特别是有时候啃官方文档的时候,出现一些比较绕口的词,我怎么也不能理解,所以我就会不停的反问自己,你真的理解这个词吗?之后就会琢磨好久,用自己能理解的语言写出来,并记录下来!
如果,我分享的对您有帮助,那么我们一起进步,点赞随缘,收藏随心!
什么是动态数据?
发挥一下阅读理解能力,动态数据应该指的就是不断变化的数据,非固定一成不变的数据!
常见的几种场景:
- 商城种常见的购物车数据就是不断变化的
- 购买商品支付的金额会根据选购的数量不断变化
- 字符串实时拼接等
vue实现这种需求有四种方式
1.JavaScript表达式
vue提供了一种非常方便的操作,模板语法{{}}中可以使用单一的JavaScript表达式,但只适合简单的需求(比如字符串拼接),稍微复杂的需求不建议试用!
- 例子 - 反转字符串:
<div id="example"> {{ message.split('').reverse().join('') }}</div><script type="text/javascript"> const app = new Vue({el: "#example",data:{ message: '我是一个例子!'} }) </script>复制代码
上边的反转字符串我们也可以通过定义一个方法来实现,但是这种简单的需求单独定义个方法又是大材小用了!
2.method方法
那么,假如我们有一个购物车的需求,我们要根据商品的价格和数量来计算出总价的时候,这个场景就相对复杂了,就可以使用这种方法!
<div id="app"><ul><li v-for="(item, index) in books" :key="index"><span>名称:{{item.name}}</span><span>价格:{{item.price.toFixed(2)}}</span><span>数量:{{item.num}}</span><br><input type="button" value="+" @click="item.num += 1"><input type="button" value="-" @click="item.num -= 1"></li></ul><p>总价:{{totalPrice()}}</p></div><script>var app = new Vue({el: '#app',data: {books: [ {name: 'Android',price: 12.00,num: 0},{name: 'IOS',price: 13.00,num: 0},{name: 'javaScript',price: 14.00,num: 0}, ],// totalPrice: 0.00}, methods:{ totalPrice: function(){var result = 0// forEach()获得数组的每个元素,参数为一个回调函数this.books.forEach(book => { result += book.price * book.num; });return result; } } });</script>复制代码
我们通过定义了一个方法实现了购物车基本的运算,但是我们发现,每进行一次计算,一旦触发了页面的重新渲染,totalPrice()方法都要执行一次,我们重新写个点击事件来验证下!
- 在以上代码中添加,如图:
<h1>验证</h1><p>{{testData}}</p><input type="button" value="test" @click="testMethod()">复制代码
testMethod: function(){ console.log('testMethod'); this.testData += 1},复制代码
data中别忘了声明testData属性,点击这个事件我们来验证下!
点击之后我们发现,只要我们定义的这个testMethod方法触发一次页面渲染,totalPrice方法也要跟着执行一次,那么,如果我们这个页面有很多操作事件,每一次触动渲染,它都跟着执行一次,就会造成很多性能浪费,此时,这个带有缓存功能的计算属性computed就很好的解决了这个问题!
3.computed属性
计算属性是基于它们的响应式依赖进行缓存的,只在相关响应式依赖发生改变时它们才会重新求值。
这句话什么意思呢?以刚才我们验证totalPrice方法只要有方法触发了dom的实时渲染,他都要跟着执行一次,变成现在他自己缓存起来,只要他自身不改变不触发dom渲染,你执行别的方法,它就不会再受影响!
如何定义,计算属性?
如图所示: 计算属性computed与mefthods是同级,将我们在methods中定义的totalProice方法移到computed中,名称改为totalProice1。
在data中声明一个totalProice属性,如下图:
将总价中模板语法渲染改为{{ totalPricel }}
此时,我们再去执行testMethod方法就不会影响到他的计算值!如下图:
这就是computed计算属性解决的问题!
计算属性的getter和setter方法
computed 提供了一个 getter 和 setter 方法,默认情况下,我们只需要关注 computed 的 getter 方法,看看官网给出的例子,拼接字符串:
<div id="app"> {{ fullname }} </div> <script> var app = new Vue({el: '#app',data:{ firstName: '刘', lastName: '德华'},computed:{ fullname: function(){return this.firstName + this.lastName } } })</script>复制代码
同样可以试用computed的getter方法实现,getter方法可以简写成get
computed: {fullName: {// getterget: function () { return this.firstName + ' ' + this.lastName }, } }复制代码
可以发现运行的结果是一样的,同时也可以去重写它的 setter 方法,如下:
computed: {fullName: {// getterget: function () { console.log('get方法'); return this.firstName + ' ' + this.lastName },// setterset: function (newValue) {console.log('set方法:' + newValue);var names = newValue.split(' ')this.firstName = names[0]this.lastName = names[names.length - 1] } } }复制代码
当在控制台去执行app.fullName = 'The Vue'的时候,Vue 会先调用 setter 方法为 firstName 和 lastName 赋值,然后执行 getter 方法,来返回 fullName。
4.watch属性
watch属性又叫侦听属性,顾名思义它具有时刻监听数据的作用!
当你有一些数据(结果数据)需要随着其他数据(目标数据)变动而变动时,可以使用 watch 来监听目标数据的变化,当目标数据发生变化时,Vue 会回调我们的监听事件。
注释掉,上一步定义的computed,添加如下代码,这就是watch的定义方式,需要监听哪个数据就位那个数据定义一个回调函数!
watch:{ books:{ handler: function(val, oldval){ this.totalPrice = 0; val.forEach(item => { this.totalPrice += item.num * item.price; }); }, deep: true, } },复制代码
上例中,使用 watch 属性来对 books 进行数据监听,当 books 发生数据变化时,会回调 handler 方法,handler 方法接收两个参数监听数据的当前值(val),监听数据变化之前的值(注意:当监听的数据为对象或数组时,val 和 oldVal 是相等的,因为这两个引用指向同一块内存空间),这样就可以在回调方法 handler 来计算 totalPrice。
侦听器能实现的效果很多时候都可以用计算属性来实现,那为什么还要定义这样一个方法呢,官方给的说法是:当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
意思是应用场景主要在:异步操作和性能开销较大时采用!
我们用刚才的例子加一个定时器,模拟下异步操作,改造handler回调方法!
watch: { books: {// 监听到数据变化之后的回调方法handler:function(val,oldval){this.totalPrice = '计算中...';var $this = this;setTimeout(() => { $this.totalPrice = 0; val.forEach(item => { $this.totalPrice += item.num * item.price; }); }, 1000); },deep:true// 对象内部的属性监听,也叫深度监听} },复制代码
通过上边的模拟异步请求,实现了一个计算中的效果!
四种方式的对比
截止到这里就已经了解了 Vue 中进行动态数据计算的所有方式了,我们把这些方式进行一个总结。
(1)JavaScript 表达式:方法最为简单,不需要学习新的属性和概念就可以直接使用,但是它只有简单的运用场景(比如,简单的字符串拼接),当应用常见变得复杂的时候(如购物车)这种方式就不在适用了。
(2)method 方法:method 方法的形式可以帮助我们应对一个复杂的场景,当页面重新渲染的时候,method 方法每次都会执行。如果页面有大量的渲染动作,并且大量的渲染动作与动态数据计算无关的话,使用这种方式会带来一定的性能浪费。
(3)watch 属性:使用 watch 属性可以对数据进行监听,当被监听的数据发生变化的时候,对应的数据监听方法会被调用,watch 属性同样可以帮助我们应对一个复杂的操作,并且可以提供异步的事件处理。当需要监听一个目标数据的变化时,这种方式是一种非常好的选择,同时如果目标数据有多个 (firstName、lastName),多个目标数据共同影响一个结果数据的话 (fullName),这种监听方式会让人觉得比较奇怪。
这里可以参考官方解释:
(4)computed 属性:computed 属性也是 Vue 中大力推广的一个特性,它会通过声明的方式来确定依赖的关系,只有依赖数据发生响应式变化的时候,才会调用 computed 属性的 getter 方法,并且 computed 属性默认提供了缓存机制,如果依赖数据并没有发生响应式变化,computed 属性不会重新计算,而只是读取缓存数据。
如何选择用那种: 选择那种方式实现,取决于面对了什么样的问题。
感谢您的阅读,如果对您有帮助,欢迎关注"CRMEB"掘金号。码云上有我们开源的商城项目,知识付费项目,JAVA版全开源商城系统,学习研究欢迎使用,老铁顺手点个star呗,老板奖励五毛,分你两毛五,????????关注我们保持联系!