聲明響應(yīng)式狀態(tài)
ref()
在組合式 API 中,推薦使用 ref() 函數(shù)來聲明響應(yīng)式狀態(tài): ref() 接收參數(shù),并將其包裹在一個帶有 .value 屬性的 ref 對象中返回:
import?{?ref?}?from?'vue'
const?count?=?ref(0)
console.log(count)?//?{?value:?0?}
console.log(count.value)?//?0
count.value++
console.log(count.value)?//?1
形式1 setup() 函數(shù)
-
要在組件模板中訪問 ref,請從組件的 setup() 函數(shù)中聲明并返回它們:
<script?lang="ts"?>
import?{?ref?}?from?'vue'
export?default?{
????setup()?{
????????const?count?=?ref(0)
????????function?increment()?{
????????????//?在?JavaScript?中需要?.value
????????????count.value++
????????}
????????//?不要忘記同時暴露?increment?函數(shù)
????????return?{
????????????count,
????????????increment
????????}
????}
}
</script>
<template>
????<div?class="container">
????????<div>{{?count?}}</div>
????????<button?@click="count++">
????????????{{?count?}}
????????</button>
????</div>
</template>
<style??scoped>
.container?{}
</style>
-
注意,在模板中使用 ref 時,我們不需要附加 .value。為了方便起見,當(dāng)在模板中使用時,ref 會自動解包 (有一些注意事項)。
在模板渲染上下文中,只有頂級的 ref 屬性才會被解包。
在下面的例子中,count 和 object 是頂級屬性,但 object.id 不是:
const?count?=?ref(0)
const?object?=?{?id:?ref(1)?}
//模版正常渲染執(zhí)行
{{?count?+?1?}}?
//模版不會正常渲染非頂級不會被解包仍然是一個ref
{{?object.id?+?1?}}??對象
//我們可以將?id?解構(gòu)為一個頂級屬性
const?{?id?}?=?object
{{?id?+?1?}}???//模版正常渲染并執(zhí)行
//模版自動解包
{{?object.id?}}
該特性僅僅是文本插值的一個便利特性,等價于?{{?object.id.value?}}
形式2 <script setup>
-
在 setup() 函數(shù)中手動暴露大量的狀態(tài)和方法非常繁瑣。
-
幸運(yùn)的是,我們可以通過使用單文件組件 (SFC) 來避免這種情況。我們可以使用 <script setup> 來大幅度地簡化代碼:
<script?setup?lang="ts">
import?{?ref?}?from?'vue'
const?count?=?ref(0)
function?increment()?{
????count.value++
}
</script>
<template>
????<button?@click="increment">
????????{{?count?}}
????</button>
</template>
深層響應(yīng)性
-
Ref 可以持有任何類型的值,包括深層嵌套的對象、數(shù)組或者 JavaScript 內(nèi)置的數(shù)據(jù)結(jié)構(gòu),比如 Map。
-
Ref 會使它的值具有深層響應(yīng)性。這意味著即使改變嵌套對象或數(shù)組時,變化也會被檢測到:
<script?setup?lang="ts">
import?{?ref?}?from?'vue'
const?count?=?ref(0)
const?obj?=?ref({
????nested:?{?count:?0?},
????arr:?['foo',?'bar']
})
function?mutateDeeply()?{
????//?以下都會按照期望工作
????obj.value.nested.count++
????obj.value.arr.push('baz')
}
function?increment()?{
????count.value++
}
</script>
<template>
????{{?obj.arr?}}
????<button?@click="mutateDeeply">
????????{{?obj.nested.count?+?1?}}
????</button>
</template>
shallow ref
可以通過 shallow ref 來放棄深層響應(yīng)性
-
減少大型不可變數(shù)據(jù)的響應(yīng)性開銷
-
與外部狀態(tài)系統(tǒng)集成
DOM 更新時機(jī)
-
當(dāng)你修改了響應(yīng)式狀態(tài)時,DOM 會被自動更新。但是需要注意的是,DOM 更新不是同步的。
-
Vue 會在“next tick”更新周期中緩沖所有狀態(tài)的修改,以確保不管你進(jìn)行了多少次狀態(tài)修改,每個組件都只會被更新一次。文章來源:http://www.zghlxwxcb.cn/news/detail-802606.html
要等待 DOM 更新完成后再執(zhí)行額外的代碼,可以使用 nextTick() 全局 API:文章來源地址http://www.zghlxwxcb.cn/news/detail-802606.html
<script?setup?lang="ts">
import?{?ref?}?from?'vue'
import?{?nextTick?}?from?'vue'
const?count?=?ref(0)
async?function?increment()?{
????count.value++
????console.log(document.querySelector('button')?.textContent);
????//?這里會立即打印?'0'
????await?nextTick()
????//?現(xiàn)在?DOM?已經(jīng)更新了
????console.log(document.querySelector('button')?.textContent);
????//?這里會立即打印?'1'
}
</script>
<template>
????<button?@click="increment">
????????{{?count?}}
????</button>
</template>
到了這里,關(guān)于vue3-響應(yīng)式基礎(chǔ)之ref的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!