溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Vue+TypeScript中處理computed的方式是什么

發(fā)布時間:2022-04-02 09:15:23 來源:億速云 閱讀:991 作者:iii 欄目:開發(fā)技術(shù)

今天小編給大家分享一下Vue+TypeScript中處理computed的方式是什么的相關(guān)知識點,內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

什么是 「computed」

「computed」 是Vue中提供的一個計算屬性。它被混入到Vue實例中,所有的getter和setter的this上下文自動的綁定為Vue實例。計算屬性的結(jié)果會被緩存,除非依賴的響應(yīng)式property變化才會從新計算。

「computed」 的用途

我們可以使用 「computed」 對已有的屬性數(shù)據(jù)進(jìn)行加工處理,得到我們的目標(biāo)數(shù)據(jù)。

在TypeScript怎么用

在 「vue-class-component」 中分別為props,watch等提供了對應(yīng)的裝飾器,而 「computed」 卻沒有對應(yīng)的裝飾器提供。

官網(wǎng)的實例中,「computed」 的功能是通過 「get」 實現(xiàn)的。

<template>
  <input v-model="name">
</template>
 
<script>
import Vue from 'vue'
import Component from 'vue-class-component'
 
@Component
export default class HelloWorld extends Vue {
  firstName = 'John'
  lastName = 'Doe'
 
  // Declared as computed property getter
  get name() {
    return this.firstName + ' ' + this.lastName
  }
 
  // Declared as computed property setter
  set name(value) {
    const splitted = value.split(' ')
    this.firstName = splitted[0]
    this.lastName = splitted[1] || ''
  }
}
</script>

另一種方案

在實際項目中,將組件修改為TypeScript后,使用 get 實現(xiàn)計算屬性,瀏覽器控制臺提示data是非響應(yīng)式的,數(shù)據(jù)無法顯示。組件js版

<template>
  <el-table border :data="data"  height="400" @selection-change="selectChange">
    <el-table-column type="selection" width="55"></el-table-column>
    <el-table-column prop="code" label="編碼"></el-table-column>
    <el-table-column prop="name" label="名稱"></el-table-column>
  </el-table>
</template>
<script>
export default {
  name: 'hierarchy-table',
  props: {
    value: {
      type: Array,
      required: true
    },
    skipCodes: {
      type: Array
    }
  },
  data() {
    return {
    };
  },
  computed: {
    data() {
      return this.skipCodes ? this.value.filter(it => !this.skipCodes.includes(it.code)) : this.value;
    }
  },
  methods: {
    selectChange(selection) {
      this.$emit('selection-change', selection);
    }
  }
};
</script>

鑒于這個問題,使用創(chuàng)建中間變量的方式進(jìn)行解決。組件ts版

<template>
  <el-table border :data="data"  height="400" @selection-change="selectChange">
    <el-table-column type="selection" width="55"></el-table-column>
    <el-table-column prop="code" label="編碼"></el-table-column>
    <el-table-column prop="name" label="名稱"></el-table-column>
  </el-table>
</template>
<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
 
@Component
export default class HierarchyTable extends Vue {
  data: any[] = [];
 
  @Prop({ type: Array, required: true }) value!: any;
  @Prop({ type: Array }) skipCodes: any;
 
  @Watch('value')
  valueChanged(val) {
    this.updateData();
  }
 
  @Watch('skipCodes')
  skipCodesChanged() {
    this.updateData();
  }
 
  updateData() {
    this.data = this.skipCodes ? this.value.filter(it => !this.skipCodes.includes(it.code)) : this.value;
  }
 
  selectChange(selection) {
    this.$emit('selection-change', selection);
  }
}
</script>
 
<style scoped></style>

vue computed正確使用方式 

最近面試中,遇到一個小伙子,談到了vue中的computed和watch區(qū)別,最后得到了一個讓我瞠目結(jié)舌的答案,只用watch,從不用computed

模板內(nèi)的表達(dá)式非常便利,但是設(shè)計它們的初衷是用于簡單運算的。在模板中放入太多的邏輯會讓模板過重且難以維護(hù),所以,對于復(fù)雜邏輯,vue 提倡使用計算屬性。需要特別說明:計算屬性的 getter 函數(shù)是沒有副作用 (side effect) 的,這使它更易于測試和理解 &mdash; from Vue計算屬性

討論 computed 和 watch 之間的區(qū)別前,我們先看下 computed 和 methods 有何區(qū)別?

computed or methods

理論上,computed 所有實現(xiàn)可以使用 methods 完全替換。

<p>Reversed message: "{{ reversedMessage() }}"</p>
<p>Reversed message: "{{ reversedMessage }}"</p>
// 計算屬性
computed: {
  reversedMessage () {
    return this.message.split('').reverse().join('')
  }
}
// 方法
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

計算屬性是基于它們的響應(yīng)式依賴進(jìn)行緩存的。只在相關(guān)響應(yīng)式依賴發(fā)生改變時它們才會重新求值。這就意味著只要 message 還沒有發(fā)生改變,多次訪問 reversedMessage計算屬性會立即返回之前的計算結(jié)果,而不必再次執(zhí)行函數(shù)。而方法卻會執(zhí)行。

這也同樣意味著下面的計算屬性將不再更新,因為 Date.now() 不是響應(yīng)式依賴:

computed: {
  now: function () {
    return Date.now()
  }
}

我們?yōu)槭裁葱枰彺??假設(shè)我們有一個性能開銷比較大的計算屬性 A,它需要遍歷一個巨大的數(shù)組并做大量的計算。然后我們可能有其他的計算屬性依賴于 A 。如果沒有緩存,我們將不可避免的多次執(zhí)行 A 的 getter!如果你不希望有緩存,請用方法來替代。

相同之處: computed 和 methods 將被混入到 Vue 實例中。vm.reversedMessage/vm.reversedMessage() 即可獲取相關(guān)計算屬性/方法。

接下來,看下 computed 和 watch 有何區(qū)別?

computed or watch

Vue 提供了一種更通用的方式來觀察和響應(yīng) Vue 實例上的數(shù)據(jù)變動:偵聽屬性。當(dāng)你有一些數(shù)據(jù)需要隨著其它數(shù)據(jù)變動而變動時,你很容易濫用 watch,然而,通常更好的做法是使用計算屬性而不是命令式的 watch 回調(diào)。

當(dāng)需要在數(shù)據(jù)變化時執(zhí)行異步或開銷較大的操作時, watch 方式是最有用的。其允許我們執(zhí)行異步操作 (訪問一個 API),限制我們執(zhí)行該操作的頻率,并在我們得到最終結(jié)果前,設(shè)置中間狀態(tài)。這些都是計算屬性無法做到的。

methods: {
  getAnswer: function () {
    this.answer = 'Thinking...'
    var vm = this
    axios.get('https://yesno.wtf/api')
      .then(function (response) {
        vm.answer = _.capitalize(response.data.answer)
      })
      .catch(function (error) {
        vm.answer = 'Error! Could not reach the API. ' + error
      })
  }
},
created: function () {
  // debounce 反彈函數(shù)
  this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
}

這樣來看,watch 完全可以替代 computed ?什么情況下,只能使用computed呢?

回顧 computed 最大特點就是緩存,所以上述問題可以轉(zhuǎn)換為:哪些情況下,我們需要依賴緩存?

示例:父組件給子組件傳值,值的類型為引用類型

父組件

<template>
  <div>
    <child :user="user"></child>
    <label for="user">parent:</label>
    <input id="user" type="text" v-model="user.name">
  </div>
</template>
<script>
import Child from './child.vue'
export default {
  data () {
    return {
      user: { name: 'ligang' }
    }
  },
  components: { Child }
}
</script>

子組件

<template>
  <div>child: {{user}}</div>
</template>
<script>
export default {
  name: 'child',
  props: ['user']
}
</script>

現(xiàn)在有這樣一個需求,子組件中需要同時顯示改變前和改變后的值。

So Easy,只需要在 watch 中保存 oldVal 即可。

<template>
  <div>
    <div>child:</div>
    <div>修改前:{{oldUser}} 修改后:{{user}}</div>
  </div>
</template>
<script>
export default {
  name: 'child',
  props: ['user'],
  data () {
    return {
      oldUser: {}
    }
  },
  watch: {
    user: {
      handler (val, oldVal) {
        this.oldUser = oldVal || val
      },
      deep: true,
      immediate: true
    }
  }
}
</script>

查看結(jié)果,WTF,啥情況~~

Vue+TypeScript中處理computed的方式是什么

問題在于,user為引用類型,且 watch 沒有做緩存,導(dǎo)致了修改的是同一個對象,所以,watch 方法中**val === olVal is true?。?*

如何達(dá)到要求呢,這里我們就可以借用 computed 緩存的特性,來完成上述情況。

計算屬性的結(jié)果會被緩存,除非依賴的響應(yīng)式屬性變化才會重新計算。注意,如果某個依賴 (比如非響應(yīng)式屬性) 在該實例范疇之外,則計算屬性是不會被更新的。 &mdash; vue-computed-api

<template>
  <div>
    <div>child:</div>
    <div>修改前:{{oldUser}} 修改后:{{user}}</div>
  </div>
</template>
<script>
export default {
  name: 'child',
  props: ['user'],
  data () {
    return {
      oldUser: {}
    }
  },
  // 緩存 userInfo   
  computed: {
    userInfo () {
      return { ...this.user }
    }
  },
  watch: {
    userInfo: {
      handler (val, oldVal) {
        this.oldUser = oldVal || val
      },
      deep: true,
      immediate: true
    }
  }
}
</script>

需要注意:{ ...this.user } 或者使用 Object.assign({}, this.user) 來創(chuàng)建新的引用!

以上就是“Vue+TypeScript中處理computed的方式是什么”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI