vue計(jì)算屬性及使用詳解
一、什么是計(jì)算屬性
模板內(nèi)的表達(dá)式非常便利,但是設(shè)計(jì)它們的初衷是用于簡單運(yùn)算的。在模板中放入太多的邏輯會讓模板過重且難以維護(hù)。例如:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
這里的表達(dá)式包含3個(gè)操作,并不是很清晰,所以遇到復(fù)雜邏輯時(shí)應(yīng)該使用Vue特帶的計(jì)算屬性computed來進(jìn)行處理。
二、計(jì)算屬性的用法
在一個(gè)計(jì)算屬性里可以完成各種復(fù)雜的邏輯,包括運(yùn)算、函數(shù)調(diào)用等,只要最終返回一個(gè)結(jié)果就可以。
我們把上面的例子用計(jì)算屬性的方式重寫一下
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p> //我們把復(fù)雜處理放在了計(jì)算屬性里面了
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
reversedMessage: function () {
// `this` 指向 vm 實(shí)例
return this.message.split('').reverse().join('')
}
}
});
結(jié)果:
Original message: "Hello"
Computed reversed message: "olleH"
除了上例簡單的用法,計(jì)算屬性還可以依賴多個(gè)Vue 實(shí)例的數(shù)據(jù),只要其中任一數(shù)據(jù)變化,計(jì)算屬性就會重新執(zhí)行,視圖也會更新。
<body>
<div id="app">
<button @click="add()">補(bǔ)充貨物1</button>
<div>總價(jià)為:{{price}}</div>
</div>
</body>
var app = new Vue({
el: '#app',
data: {
package1: {
count: 5,
price: 5
},
package2: {
count: 10,
price: 10
}
},
computed: {
price: function(){
return this.package1.count*this.package1.price+this.package2.count*this.package2.price //總價(jià)隨著貨物或價(jià)格的改變會重新計(jì)算
}
},
methods: { //對象的方法
add: function(){
this.package1.count++
}
}
});
計(jì)算屬性還有兩個(gè)很實(shí)用的小技巧容易被忽略:一是計(jì)算屬性可以依賴其他計(jì)算屬性; 二是計(jì)算屬性不僅可以依賴當(dāng)前Vue 實(shí)例的數(shù)據(jù),還可以依賴其他實(shí)例的數(shù)據(jù),例如:
<div id="app1"></div>
<div id="app2">{{ reverseText}}</div>
var app1 = new Vue({
el: '#app1',
data: {
text: 'computed'
}
});
var app2 = new Vue({
el: '#app2',
computed: {
reverseText: function(){
return app1.text.split('').reverse().join(''); //使用app1的數(shù)據(jù)進(jìn)行計(jì)算
}
}
});
每一個(gè)計(jì)算屬性都包含一個(gè)getter 和一個(gè)setter ,我們上面的兩個(gè)示例都是計(jì)算屬性的默認(rèn)用法, 只是利用了getter 來讀取。
在你需要時(shí),也可以提供一個(gè)setter 函數(shù), 當(dāng)手動(dòng)修改計(jì)算屬性的值就像修改一個(gè)普通數(shù)據(jù)那樣時(shí),就會觸發(fā)setter 函數(shù),執(zhí)行一些自定義的操作,例如:
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[names.length - 1];
}
}
}
});
//現(xiàn)在再運(yùn)行 vm.fullName = 'John Doe' 時(shí),setter 會被調(diào)用,vm.firstName 和 vm.lastName 也會相應(yīng)地被更新。
絕大多數(shù)情況下,我們只會用默認(rèn)的getter 方法來讀取一個(gè)計(jì)算屬性,在業(yè)務(wù)中很少用到setter,所以在聲明一個(gè)計(jì)算屬性時(shí),可以直接使用默認(rèn)的寫法,不必將getter 和setter 都聲明。
三、計(jì)算屬性緩存
上面的例子,除了使用計(jì)算屬性外,我們也可以通過在表達(dá)式中調(diào)用方法來達(dá)到同樣的效果,如:
<div>{{reverseTitle()}}</div>
// 在組件中
methods: {
reverseTitle: function () {
return this.title.split('').reverse().join('')
}
}
我們可以將同一函數(shù)定義為一個(gè)方法而不是一個(gè)計(jì)算屬性,兩種方式的最終結(jié)果確實(shí)是完全相同的。只是一個(gè)使用reverseTitle()取值,一個(gè)使用reverseTitle取值。
然而,不同的是計(jì)算屬性是基于它們的依賴進(jìn)行緩存的。計(jì)算屬性只有在它的相關(guān)依賴發(fā)生改變時(shí)才會重新求值。
這就意味著只要 title還沒有發(fā)生改變,多次訪問 reverseTitle計(jì)算屬性會立即返回之前的計(jì)算結(jié)果,而不必再次執(zhí)行函數(shù)。
舉個(gè)小例子:
<div>{{reverseTitle}}</div>
<div>{{reverseTitle1()}}</div>
<button @click="add()">補(bǔ)充貨物1</button>
<div>總價(jià)為:{{price}}</div>
computed: {
reverseTitle: function(){
return this.title.split('').reverse().join('') //而使用計(jì)算屬性,只要title沒變,頁面渲染是不會重新進(jìn)這里來計(jì)算的,而是使用了緩存。
},
price: function(){
return this.package1.count*this.package1.price+this.package2.count*this.package2.price
}
},
methods: { //對象的方法
add: function(){
this.package1.count++
},
reverseTitle1: function(){
return this.title.split('').reverse().join('') //點(diǎn)擊補(bǔ)充貨物,也會進(jìn)這個(gè)方法,再次計(jì)算。不是刷新,而是只要頁面渲染,就會進(jìn)方法里重新計(jì)算。
}
},
相比之下,每當(dāng)觸發(fā)重新渲染時(shí),調(diào)用方法將總會再次執(zhí)行函數(shù)。
我們?yōu)槭裁葱枰彺??假設(shè)我們有一個(gè)性能開銷比較大的的計(jì)算屬性 A,它需要遍歷一個(gè)巨大的數(shù)組并做大量的計(jì)算。然后我們可能有其他的計(jì)算屬性依賴于 A 。
如果沒有緩存,我們將不可避免的多次執(zhí)行 A 的 getter!如果你不希望有緩存,請用方法來替代。
下面看下Vue計(jì)算屬性的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>計(jì)算屬性</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<script src="../js/Vue.js"></script>
<script src="../js/vue-resource.js"></script>
<script>
window.onload = function(){
var vm = new Vue({
el:'#box',
data: {
a: 1,
},
computed:{
b:function(){
return this.a+1;
}
}
});
console.log(vm.a);
}
</script>
</head>
<body>
<div id="box">
a => {{a}}
<br>
b => {}
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>計(jì)算屬性</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<script src="../js/Vue.js"></script>
<script src="../js/vue-resource.js"></script>
<script>
window.onload = function(){
var vm = new Vue({
el:'#box',
data: {
a: 1,
},
computed:{
b:function(){
return this.a+1;
}
}
});
document.onclick = function(){
vm.a = 101;
}
}
</script>
</head>
<body>
<div id="box">
a => {{a}}
<br>
b => {}
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>計(jì)算屬性</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<script src="../js/Vue.js"></script>
<script src="../js/vue-resource.js"></script>
<script>
window.onload = function(){
var vm = new Vue({
el:'#box',
data: {
a: 1,
},
computed:{
b:{
get:function(){
return this.a+2;
},
set:function(val){
this.a=val;
}
}
}
});
document.onclick = function(){
vm.b = 10;
}
}
</script>
</head>
<body>
<div id="box">
a => {{a}}
<br>
b => {}
</div>
</body>
</html>
總結(jié)
以上所述是小編給大家介紹的vue計(jì)算屬性及使用詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
vue3為什么要用proxy替代defineProperty
這篇文章主要介紹了vue3為什么要用proxy替代defineProperty,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
Vue 中文本內(nèi)容超出規(guī)定行數(shù)后展開收起的處理的實(shí)現(xiàn)方法
這篇文章主要介紹了Vue 中文本內(nèi)容超出規(guī)定行數(shù)后展開收起的處理的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
淺談Vue中的this.$store.state.xx.xx
這篇文章主要介紹了Vue中的this.$store.state.xx.xx用法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
詳解vue-cli與webpack結(jié)合如何處理靜態(tài)資源
本篇文章主要介紹了詳解vue-cli與webpack結(jié)合如何處理靜態(tài)資源,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09
詳解在vue-cli項(xiàng)目中安裝node-sass
本篇文章主要介紹了詳解在vue-cli項(xiàng)目中安裝node-sass ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
如何為vuex實(shí)現(xiàn)帶參數(shù)的 getter和state.commit
這篇文章主要介紹了如何為vuex實(shí)現(xiàn)帶參數(shù)的getter和state.commit,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01
Vue函數(shù)式組件的應(yīng)用實(shí)例詳解
這篇文章主要介紹了Vue函數(shù)式組件的應(yīng)用實(shí)例詳解,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08
vue復(fù)雜表格單元格合并根據(jù)數(shù)據(jù)動(dòng)態(tài)合并方式
這篇文章主要介紹了vue復(fù)雜表格單元格合并根據(jù)數(shù)據(jù)動(dòng)態(tài)合并方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02
vue ssr+koa2構(gòu)建服務(wù)端渲染的示例代碼
這篇文章主要介紹了vue ssr+koa2構(gòu)建服務(wù)端渲染的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03

