詳解Vue之計算屬性
模板內(nèi)的表達式通常用于簡單的運算,當其過長或邏輯復復雜時,會變得難以維護
什么是計算屬性
在Vue應用中,在模板中雙向綁定一些數(shù)據(jù)或者表達式,但是表達式如果過長,或者邏輯更為復雜時,就會變得臃腫甚至難以維護和閱讀,比如
<div>
{{text.split(',').reverse().join(',')}}
</div>.
這里表達式包含三個操作,并不是很清晰,所以在遇到復雜的邏輯時應該使用計算屬性,上例可以用計算屬性進行改寫:
<div id="CalculationProperties">
{{ReversedText}}
</div>
<script>
var CalculationProperties = new Vue({
el: "#CalculationProperties",
data: {
text:"123,456",
},
computed: {
ReversedText: function ()
{
//所有計算屬性都以函數(shù)的形式寫在Vue實例內(nèi)的computed選項內(nèi),最終返回計算后的結(jié)果
return this.text.split(',').reverse().join(',')
}
}
})
</script>
所有計算屬性都以函數(shù)的形式寫在Vue實例內(nèi)的computed選項內(nèi),最終返回計算后的結(jié)果
計算屬性用法
在一個計算屬性里可以完成各種復雜的邏輯,包括邏輯運算、函數(shù)調(diào)用等,只要最終返回一個結(jié)果就可以。除了上面的簡單的用法,計算屬性還可以依賴多個vue實例的數(shù)據(jù),只要其中人一個數(shù)據(jù)變化,計算屬性就會重新執(zhí)行,視圖也會更新,例如下面的例子展示的是購物車內(nèi)兩個包裹的物品總價
<div id="prices">
總價: {{prices}}
</div>
<script>
// <!--購物車總價-->
var prices = new Vue({
el: "#prices",
data: {
package1: [
{
name: "華為mate20pro",
price: 4566,
count: 2
},
{
name: "華為p30",
price: 4166,
count: 2
},
],
package2: [
{
name: "蘋果",
price: 30,
count: 2
},
{
name: "香蕉",
price: 2,
count: 20
},
]
},
computed: {
prices: function () {
var prices = 0;
debugger
for (var i = 0; i < this.package1.length; i++) {
prices += this.package1[i].price * this.package1[i].count;
}
for (var i = 0; i < this.package2.length; i++) {
prices += this.package2[i].price * this.package2[i].count;
}
return prices;
}
}
})
</script>
當package1或package2中的商品發(fā)生變化,比如購買數(shù)量變化或者增刪商品時,計算屬性prices就會自動更新,視圖中的總價也會自動變化
每個計算屬性都包含一個getter和setter,上面的例子都是計算屬性默認用法,只是利用了getter來讀取。在你需要時,也可以提供一個setter函數(shù),當手動修改計算屬性的值就像修改一個普通數(shù)據(jù)那樣,就會觸發(fā)setter函數(shù),執(zhí)行一些自定義的操作。
<!--setter-->
<div id="setter">
姓名: {{fullName}}
</div>
<script>
var setter = new Vue({
el: "setter",
data: {
firstName: 'Jack',
lastName:'Green'
},
computed: {
fullName: {
//getter,用于讀取
get: function ()
{
return this.firstName + ' ' + this.lastName
},
//setter,寫入時觸發(fā)
set: function (newValue)
{
var names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[1];
}
}
}
})
</script>
當執(zhí)行 setter.fullName='Join Doe'時候,setter就會被調(diào)用,數(shù)據(jù)firstName和lastName都會相對更新,視圖同樣也會更新
絕大多情況下,我們只會使用默認的getter方法來讀取一個計算屬性,在業(yè)務(wù)中很少使用到setter,所以在聲明一個計算屬性的時候,可以直接使用默認的寫法,不必將getter和setter都聲明
計算屬性除啦以上簡單的文本插值外,還經(jīng)常用于動態(tài)的設(shè)置元素的樣式名稱class和內(nèi)聯(lián)樣式style,當使用組件時,計算屬性也經(jīng)常用來動態(tài)傳遞props以后,我會慢慢介紹到
計算屬性還有兩個很使用的小技巧很容易被忽略,一是計算屬性可以依賴其他計算屬性,二是計算屬性不僅可以依賴當前Vue實例的數(shù)據(jù),還可以依賴其他Vue實例的數(shù)據(jù)
<div id="app1"></div>
<div id="app2">
{{reversedText}}
</div>
<script>
var app1 = new Vue({
el: "#app1",
data: {
text: "123,456"
}
});
var app2 = new Vue({
el: "#app2",
computed: {
reversedText: function () {
//這里是依賴app1實例中的數(shù)據(jù)text
return app1.text.split(',').reverse().join(',')
}
}
})
</script>
這里我們創(chuàng)建了兩個vue實例app1和app2,在app2的計算屬性reversedText中,依賴的是app1的數(shù)據(jù)text,所以當text變化時,實例app2的計算屬性也會變化,這樣的用法以后用到的也會比較多,尤其是在多人協(xié)同開發(fā)時很常用,以為你寫的組件所用到的數(shù)據(jù)需要依賴他人的組件提供,以后接觸的多了就會慢慢的意識到這一點。
計算屬性緩存
其實細心的話就會發(fā)現(xiàn),調(diào)用methods里的方法也能實現(xiàn)和計算屬性一樣的效果,甚至有的方法還能接收參數(shù),使用起來更加的靈活,既然使用methods就可以實現(xiàn),那為什么還需要計算屬性呢?原因就是計算屬性是基于他的依賴緩存的。一個計算屬性所依賴的數(shù)據(jù)發(fā)生變化時,他才會重新取值,所以依賴的text只要不改變。計算屬性也就不更新
computed:{
now:function()
{
return Date.now()
}
}
這里的Date.now()不是響應式依賴,所以計算屬性now 不會更新,但是methods則不同,只要重新渲染他就會被調(diào)用,因此函數(shù)也會被執(zhí)行。
使用計算屬性還是methods取決于你是否需要緩存,當遍歷大數(shù)組和做大量計算時,應當使用計算屬性,除非你不希望得到緩存
以上就是詳解Vue之計算屬性的詳細內(nèi)容,更多關(guān)于vue 計算屬性的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue.js中created()與activated()的個人使用解讀
這篇文章主要介紹了vue.js中created()與activated()的個人使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
elementplus實現(xiàn)多級表格(最后一級展示圖片)
本文主要介紹了elementplus實現(xiàn)多級表格(最后一級展示圖片),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-05-05
Electron自動更新失效報錯Error:?Object?has?been?destroyed的問題解決
本文主要講解如何解決?Error:?Object?has?been?destroyed?這個?Electron?中最常見的問題,以及?Electron?自動更新的流程,文中通過代碼示例給大家講解的非常詳細,需要的朋友可以參考下2024-01-01
Vue父子組建的簡單通信之控制開關(guān)Switch的實現(xiàn)
這篇文章主要介紹了Vue父子組建的簡單通信之控制開關(guān)Switch的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06

