Vue 계산 속성은 무엇을 할 수 있나요? 어떤 시나리오에 적용할 수 있나요? 다음 기사에서는 Vue 계산 속성을 이해하고 이를 메서드 및 시계와 비교하는 데 도움이 되기를 바랍니다.
Vue에서 계산된 속성은 모든 속성의 계산이며, 이러한 계산은 모두 필터링 방향으로 이루어집니다. 데이터의 지속적인 변화를 통해 다양한 값이 계산되고 다양한 연산 방법이 계산됩니다. Vue에서는 계산된 속성이 사용되는 일반적인 시나리오는 다음과 같습니다:
템플릿의 표현식
v-bind
속성에서 수행할 수 있는 표현식. (학습 영상 공유: vue 영상 튜토리얼) v-bind
里可以进行的表达式。(学习视频分享:vue视频教程)
指令中可以进行的表达式
以上三者的主要优势是简洁。如果只是一个小操作,比如说一些简单的数值++
,字符拼接,三元表达式,那么使用相当方便。当然,以上方式也有自己的劣势。一旦要处理的逻辑复杂,代码量就会变得大得多,而且难于维护。比如说用到if语句来控制流程。那么这个时候可能会想到用filter
,咱们来看一个简单的示例。
<div id="app"> <button @click="count++">{{count + '分'}}</button> <div> <input v-model="message" /> </div> <p>{{ message.split(' ').reverse().join(' ') }}</p> </div>
let app = new Vue({ el: '#app', data () { return { count: 0, message: '' } } })
效果如下:
从上面的示例中我们可以看出:
我们在模板内使用字符串拼接,{{count + '分'}}
通过v-bind
指定绑定了一个click
事件,它只做了一件事情,就是count++
,button
每点击一次,count
值增加1
,注意,这里并没有使用methods
input
通过v-model
做了数据双向绑定,绑定了message
,并且在p
标签中对message
字符串进行反转。
在p
标签中对message
进行计算转换的时候,是不是觉得语义不是很强烈,那么用什么办法更好呢?这就需要我们使用到前面提到的filter。
我们可以使用filter
来修改前面的示例。事实下,在Vue中使用filter
具有自己的优势,也具有自己的劣势:
优势:filter
给我们用于计算和过滤一些模板表达式和v-bind
属性表达式一些弊端的地方进行计算,他们会返回当前计算的值,可以进行传参在多地方共用这个过滤方法
劣势
:如果我们要计算多个数据不同变化结合而成的地方,那么filter
就比较难过滤到了,本质上filter
就是一个一对一的行为,对单个数据进行过滤,可以进行传参,同方法,但不同参
把上面的示例,用filter
修改之后就像下面这样:
<div id="app"> <button @click="count++">{{count + '分'}}</button> <div> <input v-model="message" /> </div> <p>{{ message | reverseString }}</p> </div> let app = new Vue({ el: '#app', data () { return { count: 0, message: '' } }, filters: { reverseString (value) { if (!value) return '' value = value.split('').reverse().join('') return value } } })
在这个示例中,我们使用filter来实现,很明显代码量多了那么一点点,但整体的语意化就变得相当明显了,让人一看这里就要进行一些过滤计算,看到reverseString就知道是字符串反转。
前面说了这么多,其实我们都是为了给computed
的应用场景做一个铺垫。那问题又来了,computed
可以做些什么?又能应用于什么场景呢?
Vue中的computed
其实规避了模板语法和filter
两个所有的劣势,他的优势在于通过计算所有依赖的数据进行计算,然后返回一个值,记住可以依赖方法里所有的数据,只要一个数据发生变化,则会重新计算,来更新视图的改变。是不是很意思,迫切的想知道它是怎么玩。
咱们还是拿使用场景来说事吧。先给大家演示一个简单实用的应用场景,后面再做一个更好玩一点的应用场景。
大家是否还记得,我们在玩微博的时候,发微博会有一个字数限制,比如说只限输入140
++
, 문자 접합, 삼항식 등의 작은 연산이라면 사용하기 꽤 편리합니다. 물론 위의 방법들 역시 단점이 있습니다. 처리해야 할 로직이 복잡해지면 코드의 양이 훨씬 많아지고 유지 관리가 어려워집니다. 예를 들어 if 문은 프로세스를 제어하는 데 사용됩니다. 그렇다면 이때는 filter
를 사용하는 것을 생각해 보도록 하겠습니다. 🎜<div id="app"> <div class="twitter"> <img :src="imgUrl" / alt="Vue 계산 속성은 무엇을 할 수 있나요? 애플리케이션 시나리오에 대한 간략한 분석" > <div class="content"> <textarea v-model="content" :maxlength="totalcount">有什么新鲜事情?</textarea> <p>您还可以输入{{ reduceCount }}字</p> </div> </div> </div> let app = new Vue({ el: '#app', data () { return { imgUrl: '//pbs.twimg.com/profile_images/468783022687256577/eKHcWEIk_normal.jpeg', totalcount: 140, // 总共只给输入140字 content: '' } }, computed: { reduceCount () { return this.totalcount - this.content.length } } })rrree🎜효과는 다음과 같습니다: 🎜🎜🎜🎜위의 예에서 다음을 볼 수 있습니다. 🎜🎜🎜🎜템플릿 내에서 문자열 연결을 사용합니다.
{{count + '분'} }
🎜🎜🎜🎜 click
이벤트는 v-bind
를 통해 바인딩됩니다. count++ code>라는 한 가지 작업만 수행합니다. <code>버튼
을 클릭할 때마다 count
값이 1
씩 증가합니다. 여기서는 methods
가 사용되지 않습니다🎜🎜 🎜🎜input
은 v-model
, 바인딩된 message
및 p
Reverse를 통해 양방향 데이터 바인딩을 수행했습니다. 태그의 메시지
문자열. 🎜🎜🎜 p
태그의 message
를 계산하고 변환할 때 의미론이 그다지 강하지 않다고 생각하는데 더 좋은 방법은 무엇인가요? 이를 위해서는 앞서 언급한 필터를 사용해야 합니다. 🎜필터
를 사용하여 이전 예를 수정할 수 있습니다. 실제로 Vue에서 filter
를 사용하면 장점과 단점이 있습니다. 🎜🎜🎜🎜장점: filter
는 우리가 사용하는 것입니다. 몇 가지 단점이 있는 일부 템플릿 표현식과 v-bind
속성 표현식을 계산하고 필터링하려면 현재 계산된 값을 반환하고 매개변수를 전달하여 이 필터링 방법을 여러 위치에서 공유할 수 있습니다🎜🎜 🎜 🎜단점
: 여러 데이터가 서로 다른 변경 사항으로 결합되는 위치를 계산하려는 경우 필터
는 본질적으로 필터일대일 동작으로 단일 데이터를 필터링하므로 매개변수를 전달할 수 있습니다. 방법은 동일하지만 매개변수가 다릅니다🎜🎜🎜위의 예를 <code>filter
로 수정한 후 > 다음과 같습니다: 🎜<div id="app"> <h1>比赛时间:{{ time }}s</h1> <h2>直播播报:{{ result }}</h2> <div class="team"> <div> <span>中国队进球数:{{ team.china }}</span> <button @click="team.china++">点击中国队进一球</button> </div> <div> <span>韩国队进球数:{{ team.korea }}</span> <button @click="team.korea++">点击韩国队进一球</button> </div> </div> </div> let app = new Vue({ el: '#app', data () { return { time: 0, team: { china: 0, korea: 0 } } }, created () { let time = setInterval(() => { this.time++ if (this.time == 90) { clearInterval(time) } }, 1000) }, computed: { result () { if (this.time < 90) { if (this.team.china > this.team.korea) { return '中国队领先' } else if (this.team.china < this.team.korea) { return '韩国领先' } else { return '双方僵持' } } else { if (this.team.china > this.team.korea) { return '中国队赢' } else if (this.team.china < this.team.korea) { return '韩国队赢' } else { return '平局' } } } } })🎜🎜🎜이 예에서는 필터를 사용하여 구현합니다. 분명히 코드의 양은 조금 더 많지만 전체적인 의미는 상당히 명확해지기 때문에 사람들이 언뜻 보기에 , 여기서는 몇 가지 필터링 계산이 필요합니다. reverseString을 보면 문자열 반전이라는 것을 알 수 있습니다. 🎜
계산
의 애플리케이션 시나리오를 위한 길을 닦기 위해 여기에 있습니다. 다시 질문이 생깁니다. 계산
으로 무엇을 할 수 있나요? 어떤 시나리오에 적용할 수 있나요? Vue의 🎜🎜computed
는 실제로 템플릿 구문과 filter
의 모든 단점을 방지합니다. 그 장점은 모든 종속 데이터를 계산한 다음 값을 반환한다는 것입니다. 메소드의 모든 데이터에 의존할 수 있습니다. 하나의 데이터가 변경되면 뷰 변경 사항을 업데이트하기 위해 다시 계산됩니다. 흥미롭지 않나요? 어떻게 작동하는지 알고 싶습니다. 🎜🎜사용 시나리오에 대해 이야기해 보겠습니다. 먼저 간단하고 실용적인 응용 시나리오를 보여드리고 나중에 더 흥미로운 응용 시나리오를 만들어 보겠습니다. 🎜🎜저희가 웨이보를 할 때 웨이보에 글을 올릴 때 140
자만 입력할 수 있다는 문자 제한이 있었던 것을 아직도 기억하시나요? 사용자 경험을 향상시키기 위해 텍스트 필드에 내용을 입력할 때 입력할 수 있는 문자 수를 알려주는 프롬프트 메시지도 있습니다. 그러면 Vue를 사용하여 이러한 작업을 수행하는 것이 훨씬 쉬울 것입니다. 예를 들어 다음 예는 다음과 같습니다. 🎜<div id="app"> <h1>比赛时间:{{ time }}s</h1> <h2>直播播报:{{ result }}</h2> <div class="team"> <div> <span>中国队进球数:{{ team.china }}</span> <button @click="team.china++">点击中国队进一球</button> </div> <div> <span>韩国队进球数:{{ team.korea }}</span> <button @click="team.korea++">点击韩国队进一球</button> </div> </div> </div> let app = new Vue({ el: '#app', data () { return { time: 0, team: { china: 0, korea: 0 }, result: '双方僵持' } }, created () { let time = setInterval(() => { this.time++ if (this.time == 90) { clearInterval(time) } }, 1000) }, wacth: { time (value, oldval) { if (value < 90) { if (this.team.china > this.team.korea) { this.result = '中国队领先' } else if (this.team.china < this.team.korea) { this.result = '韩国队领先' } else { this.result = '双方僵持' } } else { if (this.team.china > this.team.korea) { this.result = '中国队赢' } else if (this.team.chian < this.team.korea) { this.result = '韩国队赢' } else { this.result = '平局' } } }, team (value, oldval) { if (this.time < 90) { if (value.china > value.korea) { this.result = '中国队领先' } else if (value.china < value.korea) { this.result = '韩国队领先' } else { this.result = '双方僵持' } } else { if (value.china > value.korea) { this.result = '中国队赢' } else if(value.chian < value.korea) { this.result = '韩国队赢' } else { this.result = '平局' } } } } })🎜효과는 다음과 같습니다.🎜
你可以尝试在文本域中输入内容,你将体验的效果类似下图一样:
在computed
创建了一个reduceCount
,一直在监听文字的字符长度,来再次进行计算,返回值给视图,让视图进行变化。这也是一个很简单的示例。前面也提到过,我们可以监听多个数据,只要一个数据变了,整个方法就会重新计算,然后反馈到视图,这个方法只是一个简单的应用。咱们再来看一个示例,这样会更好的帮助我们理解。
这个示例是一个足球比赛记分的示例。简单的对示例进行分析:
比赛时间,用time
来维护
比赛双方的进球数,用对象team
来维护
比赛的播报情况,在90分钟内,要显示中国领先或者韩国领先或者双方僵持,如果到了90分钟我们要显示中国队赢还是韩国队赢,还是平局
第三个数据相对而言比较复杂,也是比较关键的数据。那么我们用什么方式来维护,可以说比赛情况是多样化的,用一个数据去定死,这样不符合我们的场景。那么我们先列出将会改变的地方:
我们需要检测双方的进球数
通过时间来比对,确定比赛是否结果,然后显示对应的方案
这样我们就要不断的监听两个维护的数据,一是比赛时间,二是比赛两队进球数。
<div id="app"> <h1>比赛时间:{{ time }}s</h1> <h2>直播播报:{{ result }}</h2> <div class="team"> <div> <span>中国队进球数:{{ team.china }}</span> <button @click="team.china++">点击中国队进一球</button> </div> <div> <span>韩国队进球数:{{ team.korea }}</span> <button @click="team.korea++">点击韩国队进一球</button> </div> </div> </div> let app = new Vue({ el: '#app', data () { return { time: 0, team: { china: 0, korea: 0 } } }, created () { let time = setInterval(() => { this.time++ if (this.time == 90) { clearInterval(time) } }, 1000) }, computed: { result () { if (this.time < 90) { if (this.team.china > this.team.korea) { return '中国队领先' } else if (this.team.china < this.team.korea) { return '韩国领先' } else { return '双方僵持' } } else { if (this.team.china > this.team.korea) { return '中国队赢' } else if (this.team.china < this.team.korea) { return '韩国队赢' } else { return '平局' } } } } })
看到的效果如下:
注:这里时间90分钟是一个写死的时间值。如果要让Demo更为完美,这个时间我们可以写一个90分钟的倒计时效果。如果你感兴趣的话,可以自己动手修改上面的Demo,然后在下面的评论中与我们一起分享。
这个示例中,用了点击事件来进行双方进球数,这个Demo帮助我们能能更充分的理解Vue中的computed
的含义。说到底是观察一个或多个数据,每当其中一个数据改变的时候,这个函数就会重新计算,还有就是通过观察所有数据来维护一个状态,就是所谓的返回一个状态值。从上面这个Demo,我们就可以很容易的知道computed
到底用在什么场景,如何去维护返回一个多状态的场景。
在Vue中,使用methods
可以做computed
同样的事情,不同的是,computed
可以进行缓存。什么意思呢?就是在上个例子中我们对比赛时间和两个球队的进球数进行了检测数据。如果随着时间的改变,但是球数没动,对于computed
来说只会重新计算这个球数,进入缓存,而不会再次计算,而重新计算的是这个时间,而且页面的DOM更新也会触发methods
来重新计算属性。所以,如果不想让计算属性进入缓存,请使用methods
,但我个人更推荐使用computed
,语义化会更好一点。毕竟是什么选项里就应该做什么事,methods
里面就是应该来管事件的。
computed
和watch
都可以做同一件事,就像跑步运动员都可以跑步,但是分100米和1000米,术业有专攻嘛,两个选项都是对数据进行时时监听,但是两个的适用场景就不一样了:
computed
前面说了是适用于对多数据变动进行监听,然后来维护一个状态,就是返回一个状态
wacth
是对一个数据监听,在数据变化时,会返回两个值,一个是value
(当前值),二是oldvalue
是变化前的值
我们可以通过这些变化也可以去维护一个状态,但是不符合场景。那么watch
主要用于什么地方呢?其主要用于监听一个数据来进行复杂的逻辑操作。
<div id="app"> <h1>比赛时间:{{ time }}s</h1> <h2>直播播报:{{ result }}</h2> <div class="team"> <div> <span>中国队进球数:{{ team.china }}</span> <button @click="team.china++">点击中国队进一球</button> </div> <div> <span>韩国队进球数:{{ team.korea }}</span> <button @click="team.korea++">点击韩国队进一球</button> </div> </div> </div> let app = new Vue({ el: '#app', data () { return { time: 0, team: { china: 0, korea: 0 }, result: '双方僵持' } }, created () { let time = setInterval(() => { this.time++ if (this.time == 90) { clearInterval(time) } }, 1000) }, wacth: { time (value, oldval) { if (value < 90) { if (this.team.china > this.team.korea) { this.result = '中国队领先' } else if (this.team.china < this.team.korea) { this.result = '韩国队领先' } else { this.result = '双方僵持' } } else { if (this.team.china > this.team.korea) { this.result = '中国队赢' } else if (this.team.chian < this.team.korea) { this.result = '韩国队赢' } else { this.result = '平局' } } }, team (value, oldval) { if (this.time < 90) { if (value.china > value.korea) { this.result = '中国队领先' } else if (value.china < value.korea) { this.result = '韩国队领先' } else { this.result = '双方僵持' } } else { if (value.china > value.korea) { this.result = '中国队赢' } else if(value.chian < value.korea) { this.result = '韩国队赢' } else { this.result = '平局' } } } } })
以上代码和computed
产生的效果是一模一样,但是很明显,就像我对computed
和watch
阐述过了应用场景,这个场景只是维护了一个比赛状态,而不牵扯到逻辑操作。虽然也能完成,但无论从代码量的比对还是可读性,还是可维护性的都不胜于computed
。但说到底谁更强大呢?我还是老实说watch
更强大,哪里有然他有场景的局限性,但是他可以做牵扯到计算属性的一切操作,缺点是watch
只能一个一个监听。
我相信图片预加载大家肯定都有接触过,当图片量大的时候,为了保证页面图片都加载出来的时候,才渲染页面,再进行一些 Ajax请求,或者逻辑操作。那些时你用computed
对这种监听一个数据然后进行一系列逻辑操作和Ajax
请求,那watch
再适合不过了,如果用computed
的话,那是无法实现的。
<template> <div v-show=show> <img src="https://img.alicdn.com/simba/img/TB14sYVQXXXXXc1XXXXSutbFXXX.jpg" alt=""> <img src="//img.alicdn.com/tfs/TB1iZ6EQXXXXXcsXFXXXXXXXXXX-520-280.jpg_q90_.webp" alt=""> <img src="https://img.alicdn.com/simba/img/TB1C0dOPXXXXXarapXXSutbFXXX.jpg" alt=""> <img src="//img.alicdn.com/tfs/TB1iZ6EQXXXXXcsXFXXXXXXXXXX-520-280.jpg_q90_.webp" alt=""> </div> </template> <script> export default { mounted () { var _this = this let imgs = document.querySelectorAll('img') console.log(imgs) Array.from(imgs).forEach((item)=>{ let img = new Image() img.onload = ()=>{ this.count++ } img.src=item.getAttribute('src') }) }, data () { return { count : 0, show : false } }, watch : { count (val,oldval) { if(val == 4){ this.show = true alert("加载完毕") //然后可以对后台发送一些ajax操作 } } } } </script>
我们可以发现四张图片都加载完毕的时候,页面才渲染出来。
Vue官方有一句话说得很重要:
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的
watcher
。这是为什么Vue提供一个更通用的方法,使用wacth
来响应数据的变化。当你想要在数据变化响应时,执行异步操作或开销较大的操作,这是很有用的。
基于这个描述,我对computed
和watch
的总结:
computed
:监听多个数据或者一个数据来维护返回一个状态值,只要其中一个或多个数据发生了变化,则会重新计算整个函数体,重新返回状态值
watch
:只能一个一个监听数据,只要这个数据发生变化,就会返回两个参数,第一个是当前的值,第二个是变化前的值。每当变化的时候,则会触发函数体的逻辑行为,根据逻辑行为做后续的操作
其实,computed
、watch
这几个都不是有多难,如果从表层上来说都很易理解,但从深层面上看,很多时候还是会存在问题。比如说会滥用,混用。这篇文章通过一些示例来讲解Vue的计算属性,并且对其做了一定的分析。我想这些对学习Vue的初级人员或许会有一些帮助。
原文地址:https://www.w3cplus.com/vue/vue-computed.html
위 내용은 Vue 계산 속성은 무엇을 할 수 있나요? 애플리케이션 시나리오에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!