詳解Vue3?中的計算屬性及偵聽器
計算屬性
我們知道,在模板中可以直接通過插值語法顯示一些data中的數據,但是在某些情況,我們可能需要對數據進行一些轉化后再顯示,或者需要將多個數據結合起來進行顯示
在模板中使用表達式,可以非常方便的實現,但是設計它們的初衷是用于簡單的運算,在模板中放入太多的邏輯會讓模板過重和難以維護,并且如果多個地方都使用到,那么會有大量重復的代碼
所以我們希望將業(yè)務邏輯和UI界面進行分離,其中一種方式就是將邏輯抽取到一個method中,但這種做法有以下弊端
- 所有的data使用過程都會變成了一個方法的調用
- 多次獲取數據,需要多次調用方法,執(zhí)行對應的邏輯,沒有緩存
事實上,對于任何包含響應式數據的復雜邏輯,你都應該使用計算屬性
<div id="app">
<!-- 計算屬性的使用和普通狀態(tài)的使用方式是一致的 -->
<h2>{{ fullname }}</h2>
</div>
<script>
Vue.createApp({
data() {
return {
firstname: 'Klaus',
lastname: 'Wang'
}
},
computed: {
fullname() {
return this.firstname + ' ' + this.lastname
}
}
}).mount('#app')緩存
計算屬性會基于它們的依賴關系進行緩存,在數據不發(fā)生變化時,計算屬性是不需要重新計算的
但是如果依賴的數據發(fā)生變化,在使用時,計算屬性依然會重新進行計算
并且界面會使用最新的計算屬性的值進行重新渲染
getter 和 setter
計算屬性在大多數情況下,只需要一個getter方法即可,所以我們會將計算屬性直接寫成一個函數
<div id="app">
<!-- 計算屬性的使用和普通狀態(tài)的使用方式是一致的 -->
<h2>{{ fullname }}</h2>
<button @click="change">change</button>
</div>
<script>
Vue.createApp({
data() {
return {
firstname: 'Klaus',
lastname: 'Wang'
}
},
methods: {
change() {
this.fullname = 'Alex Li'
}
},
computed: {
// 計算屬性的完整寫法
fullname: {
get() {
return this.firstname + ' ' + this.lastname
},
set(v) {
this.firstname = v.split(' ')[0]
this.lastname = v.split(' ')[1]
}
}
}
}).mount('#app')
</script>偵聽器
在data返回的對象中定義了數據,這個數據通過插值語法等方式綁定到template中,當數據變化時,template會自動進行更新來顯示最新的數據
但是在某些情況下,我們希望在代碼邏輯中監(jiān)聽某個數據的變化,這個時候就需要用偵聽器watch來完成了
Vue.createApp({
data() {
return {
info: {
name: 'Klaus'
}
}
},
watch: {
// 可以使用watch監(jiān)聽響應式數據的改變
// 對應有兩個參數
// 參數一 --- 新值
// 參數二 --- 舊值
info(newV, oldV) {
// 如果監(jiān)聽的值是對象,獲取到的新值和舊值是對應對象的代理對象
console.log(newV, oldV)
// 代理對象 轉 原生對象
// 1. 使用淺拷貝獲取一個新的對象,獲取的新的對象為原生對象
console.log({...newV})
// 2. 使用Vue.toRaw方法獲取原生對象
console.log(Vue.toRaw(newV))
}
},
methods: {
change() {
this.info = {
name: 'Steven'
}
}
}
}).mount('#app')配置選項
| 屬性 | 說明 |
|---|---|
| deep | 是否開啟深度監(jiān)聽 值為boolean 未開啟的時候,如果監(jiān)聽的是對象,那么只有對象的引用發(fā)生改變的時候,才會觸發(fā)watch回調 開始后,如果監(jiān)聽的是對象,那么只要對象中的任意一個屬性發(fā)生了改變,就會觸發(fā)watch回調 |
| immediate | 是否立即開始監(jiān)聽 默認情況下,初次渲染是不會觸發(fā)watch監(jiān)聽,只有當值發(fā)生改變后,才會觸發(fā)watch監(jiān)聽 將immediate設置為true后,初次渲染也會觸發(fā)watch監(jiān)聽,此時oldValue的值為undefined |
Vue.createApp({
data() {
return {
info: {
name: 'Klaus'
}
}
},
watch: {
info: {
// 開啟了深度監(jiān)聽后,當info的屬性發(fā)生改變的時候,就會觸發(fā)對應的watch回調
// 注意: 和直接修改info引用不同的是,如果直接修改的是對象的屬性
// 那么此時newV和oldV是同一個對象的引用, 此時也就獲取不到對應的舊值
handler(newV, oldV) {
console.log(newV, oldV)
console.log(newV === oldV) // => true
},
deep: true,
immediate: true
}
},
methods: {
change() {
this.info.name = 'Steven'
}
}
}).mount('#app')其它寫法
直接監(jiān)聽對象屬性
watch: {
'info.name'(newV, oldV){
console.log(newV, oldV)
}
}字符串寫法
Vue.createApp({
data() {
return {
info: {
name: 'Klaus'
}
}
},
watch: {
// watch的值如果是一個字符串的時候
// 會自動以該字符串作為函數名去methods中查找對應的方法
'info.name': 'watchHandler'
},
methods: {
change() {
this.info.name = 'Steven'
},
watchHandler(newV, oldV){
console.log(newV, oldV)
}
}
}).mount('#app')數組寫法
Vue.createApp({
data() {
return {
info: {
name: 'Klaus'
}
}
},
watch: {
'info.name': [
'watchHandler',
function handle() {
console.log('handler2')
},
{
handler() {
console.log('handler3')
}
}
]
},
methods: {
change() {
this.info.name = 'Steven'
},
watchHandler(){
console.log('handler1')
}
}
}).mount('#app')$watch
Vue.createApp({
data() {
return {
info: {
name: 'Klaus'
}
}
},
created() {
/*
$watch 參數列表
參數一 --- 偵聽源
參數二 --- 偵聽回調
參數三 --- 配置對象
*/
this.$watch('info.name', (newV, oldV) => console.log(newV, oldV), {
immediate: true
})
},
methods: {
change() {
this.info.name = 'Steven'
}
}
}).mount('#app')到此這篇關于詳解Vue3 中的計算屬性及偵聽器的文章就介紹到這了,更多相關Vue偵聽器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
父組件中vuex方法更新state子組件不能及時更新并渲染的完美解決方法
這篇文章主要介紹了父組件中vuex方法更新state子組件不能及時更新并渲染的完美解決方法,需要的朋友可以參考下2018-04-04
VueJs中的shallowRef與shallowReactive函數使用比較
這篇文章主要為大家介紹了VueJs中的shallowRef與shallowReactive函數的使用比較解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04
vue3?TS?vite?element?ali-oss使用教程示例
這篇文章主要為大家介紹了vue3?TS?vite?element?ali-oss使用教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07
基于elementUI使用v-model實現經緯度輸入的vue組件
這篇文章主要介紹了基于elementUI使用v-model實現經緯度輸入的vue組件,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-05-05

