一、計算屬性 computed#
1. 例子#
<div id="app">
<div>{{message}}</div>
<div>{{revermessage}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'hello,wolrd'
},
computed: {
revermessage: function() {
return this.message.split('').reverse().join('')
}
}
})
</script>
聲明一個計算屬性severmessage
,在computed
中被指向對message
進行一些方法操作後的返回值
此時vm.severmessage
依賴於vm.message
的變化,對message
改變數據,會引起severmessage
的更新
2. 計算屬性緩存和方法#
還可以通過在表達式中調用方法來達到想要的效果
<div id="app">
<div>{{message}}</div>
<div>{{revermessage()}}</div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'hello,wolrd'
},
methods: {
revermessage: function() {
return this.message.split('').reverse().join('')
}
}
})
</script>
經過測試,兩者的結果是一樣的
我們可以將同一函數定義為一個方法而不是一個計算屬性。兩種方式的最終結果確實是完全相同的
區別是:計算屬性是基於它們的響應式依賴進行緩存的,只有當響應式依賴,也就是message
發生改變時才會重新求值,就意味著,只要message
還沒改變,多次訪問revermessage
計算屬性只會返回之前計算結果的緩存,而不是直接執行計算屬性的函數
而方法,在每次觸發重新渲染時,調用方法都會執行一次函數,這就多了一份開銷
我們為什麼需要緩存?假設我們有一個性能開銷比較大的計算屬性 A,它需要遍歷一個巨大的數組並做大量的計算。然後我們可能有其他的計算屬性依賴於 A。如果沒有緩存,我們將不可避免的多次執行 A 的 getter!如果你不希望有緩存,請用方法來替代
3. 計算屬性和監聽屬性#
vue 還有一種方式來觀測 vue 實例上的數據變動:監聽屬性--watch
<div id="app">
{{fullname}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
firstname: 'a',
lastname: 'b',
fullname: 'ab'
},
watch: {
firstname: function(val) {
this.fullName = val + ' ' + this.lastName
},
lastname: function(val) {
this.fullName = this.firstName + ' ' + val
}
}
})
</script>
使用過程是極其繁瑣且重複的,再來用計算屬性試一下
<div id="app">
{{fullname}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
firstname: 'a',
lastname: 'b'
},
computed: {
fullname: function() {
return this.firstname + this.lastname
}
}
})
</script>
很簡單快速的就得到了我們想要的函數表達式
4. 計算屬性的 setter#
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]
}
}
}
現在在控制台輸入vm.fullName = 'John Doe'
,頁面會響應,並且setter
會被調用,vm.firstname
和vm.lastname
也會相應地被更新
二、綁定 class 和 style#
1. 對象語法#
可以給v-bind:class
傳入一個對象,動態的切換class
<div v-bind:class="{active: ok}"></div>
可以通過控制ok
的布爾值來動態的控制 class
還可以創建多個字段,並且不影響普通的className
的存在
html:
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>
data:
data{
isActive: true,
hasError: false
}
結果為:
<div class="static active"></div>
當isActive
或者hasError
變化時,class 列表將相應地更新。例如,如果hasError
的值為true
,class 列表將變為"static active text-danger"
。
綁定的數據對象也不必直接寫在內聯模板裡
<div id="app">
<div v-bind:class="classobject"></div>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
classobject: {
active: true,
'text-danger': true
}
},
})
</script>
<!-- <div class="active text-danger"></div> -->
如果
className
有特殊符號,必須加上引號''
,或者""
2. 數組語法#
我們可以把一個數組傳給v-bind:class
,以應用一個 class 列表
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
渲染為:
<div class="active text-danger"></div>
3. 用在組件上#
當在一個自定義組件上使用class
property 時,這些 class 將被添加到該組件的根元素上面。這個元素上已經存在的 class 不會被覆蓋。
Vue.component('my-component', {
template: '<p class="foo bar">Hi</p>'
})
然後在使用的使用的時候添加了一些class
:
<my-component class="baz boo"></my-component>
html 將會被渲染成:
<p class="foo bar baz boo">Hi</p>
對於帶數據綁定的class
也同樣適用
<my-component v-bind:class="{ active: isActive }"></my-component>
當isActive
為 truthy 時,HTML 將被渲染成為:
<p class="foo bar active">Hi</p>
4. 綁定內聯樣式 style#
v-bind:style
的對象語法十分直觀 —— 看著非常像 CSS,但其實是一個 JavaScript 對象。CSS property 名可以用駝峰式
或帶引號的短橫線
來命名
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
js:
data: {
activeColor: 'red',
fontSize: 30
}
或者直接綁定到一個對象,會讓模板更加清晰
<div v-bind:style="styleObject"></div>
js:
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
也可以將多個對象應用到一個元素上
<div v-bind:style="[baseStyles, overridingStyles]"></div>
自動添加前綴
當v-bind:style
需要使用瀏覽器前綴的時候,如:-webkit-
等,vue 會自動侦測並幫生成相應的前綴