計算屬性computed
1.什麼計算屬性
-
基礎使用:同樣是實現
data
中資料的反轉表示,有以下兩種不同寫法,,顯然第一種比第二種結構簡潔和清晰,特別是在多次使用的時候,template
裡面的程式碼將更加混亂。<p>Computed reversed message: "{{ reversedMessage }}"</p> <p>Computed reversed message: "{{message.split(``).reverse().join(``)}}"</p>
var vm = new Vue({ el: `#example`, data: { message: `Hello` }, computed: { reversedMessage: function () { // `this` points to the vm instance return this.message.split(``).reverse().join(``) }}})
-
使用場景:通過以上的使用我們可知,在需要對資料進行復雜處理,且可能多次使用的情況下,儘量採取計算屬性的方式。
-
特點:
-
①使得資料處理結構清晰;
-
②依賴於資料,資料更新,處理結果自動更新;
-
③計算屬性內部
this
指向vm例項; -
④在
template
呼叫時,直接寫計算屬性名即可; -
⑤常用的是
getter
方法,獲取資料,也可以使用set
方法改變資料; -
⑥相較於
methods
,不管依賴的資料變不變,methods
都會重新計算,但是依賴資料不變的時候computed
從快取中獲取,不會重新計算。
-
2.computed原理
//初始化計算屬性
function initComputed (vm: Component, computed: Object) {
const watchers = vm._computedWatchers = Object.create(null)
for (const key in computed) {
const userDef = computed[key]
const getter = typeof userDef === `function` ? userDef : userDef.get
//通過watch為計算屬性新增動態響應.
watchers[key] = new Watcher(vm, getter, noop, computedWatcherOptions)
//元件定義的計算屬性已經在元件原型上定義了。我們只需要在這裡定義例項化的計算屬性。
if (!(key in vm)) {
defineComputed(vm, key, userDef)}}
}
function defineComputed (target: any, key: string, userDef: Object | Function) {
//userDef如果是函式型別,只有getter
if (typeof userDef === `function`) {
sharedPropertyDefinition.get = createComputedGetter(key)
sharedPropertyDefinition.set = noop
} else {
//userDef如果是物件型別,可能存在getter或者setter
sharedPropertyDefinition.get = userDef.get
? userDef.cache !== false
? createComputedGetter(key): userDef.get: noop
sharedPropertyDefinition.set = userDef.set? userDef.set: noop}
Object.defineProperty(target, key, sharedPropertyDefinition)}
function createComputedGetter (key) {
return function computedGetter () {
const watcher = this._computedWatchers && this._computedWatchers[key]
if (watcher) {
if (watcher.dirty) {
watcher.evaluate()}
if (Dep.target) {
watcher.depend()}
return watcher.value}}}