問題記錄
這里進(jìn)行一個(gè)簡單的記錄。
今天發(fā)現(xiàn)一個(gè)小問題,在使用 ref 創(chuàng)建對象的對象無法重置為初始值。用了 kimi 和 deepseek 也沒解決這個(gè)問題。最后靈光一閃,問題解決了(還是沒解決)
先看一下有問題的代碼
const initPageInfo = {
pageNo: 1,
pageSize: 10,
total: 0,
}
const pageInfoRef = ref(initPageInfo)
在上面代碼中進(jìn)行了簡單一個(gè)分頁信息保存。在某些條件下,我希望重置這個(gè)分頁信息,于是我嘗試了以下的操作
pageInfoRef.value = {...initPageInfo}
原本以為這樣就可以了,可是萬萬沒想到,分頁其實(shí)并沒有被重置。于是我拿著我的信息問了 kimi 和 deepseek。他們告訴我要這么做
Object.assign(pageInfoRef.value, initPageInfo)
甚至還有更神的操作
pageInfoRef.value = JSON.parse(JSON.stringify(initPageInfo))
我嘗試了他們說的第一個(gè)方案,沒有效果。第二個(gè)神操作我沒有試,但是我感覺應(yīng)該不可以
解決方案
后來我忽然又靈光一閃,下面是解決方案
在第一次對 pageInfoRef 進(jìn)行初始化的時(shí)候需要更改一下方案
const pageInfoRef = ref({...initPageInfo})
原因分析(查看下面更新的內(nèi)容)
這里我并沒有分析出來具體的原因,可能與 ref 創(chuàng)建響應(yīng)式對象的方式有一定的關(guān)系。
因?yàn)槲以跍y試的過程中還嘗試下面的方式,它是卻是能進(jìn)行正常響應(yīng)式的。
我不理解這種原始的方式創(chuàng)建的對象和解構(gòu)賦值得到的對象 {...initPageInfo} 是不是有什么本質(zhì)的不同,導(dǎo)致 vue 不能正確的幫我創(chuàng)建響應(yīng)式對象?;蛟S需要看一下 vue 的相關(guān)文檔或者是看一下相關(guān)源碼了。暫時(shí)沒有時(shí)間去深究這個(gè)問題。
pageInfoRef.value = {
pageNo: 1,
pageSize: 10,
total: 0,
}
2025年7月10日 更新
今日得閑,看了一下這個(gè)文章。找到了原因
直接使用
const pageInfoRef = ref(initPageInfo)
vue 會(huì)把 initPageInfo 這個(gè)對象變成響應(yīng)式對象。
所以在后續(xù)中使用下面兩種方式,看上去似乎沒有改變 pageInfoRef,實(shí)際上是已經(jīng)改變了。只是因?yàn)?initPageInfo 的內(nèi)容已經(jīng)被 pageInfoRef.value 修改過,所以只要是使用 initPageInfo 去修改 pageInfoRef.value 不論如何,都是無法回歸初始值的
pageInfoRef.value = {...initPageInfo}
pageInfoRef.value = JSON.parse(JSON.stringify(initPageInfo))
驗(yàn)證方法
<script setup>
import { ref } from 'vue'
const initPageInfo = {
pageNo: 1,
pageSize: 10,
total: 0,
}
const pageInfoRef = ref(initPageInfo)
const changePage = (no) => {
pageInfoRef.value.pageNo = no
console.log(initPageInfo)
}
</script>
<template>
<div>
<p>pageNo: {{ pageInfoRef.pageNo }}</p>
</div>
<button @click="changePage(++pageInfoRef.pageNo)">下一頁</button>
<button @click="changePage(--pageInfoRef.pageNo)">上一頁</button>
</template>
<style scoped>
我在 changePage 函數(shù)中打印了 initPageInfo,會(huì)發(fā)現(xiàn)每次點(diǎn)上一頁或者下一頁的時(shí)候,都會(huì)改變 initPageInfo 這個(gè)對象的值
所以如果初始化 ref 的時(shí)候如果想讓 pageInfoRef 還能被重置,那么在初始化的時(shí)候就要初始化一個(gè)完全脫離原來的引用對象。
比如使用 const pageInfoRef = ref({...initPageInfo}) 如此就可以讓這個(gè) pageInfoRef 響應(yīng)式對象能被重置了
不過需要注意, {...initPageInfo} 只能處理簡單的對象,如果是要處理復(fù)雜對象,就需要深度克隆。或者把 initPageInfo 變成一個(gè)函數(shù),調(diào)用時(shí)返回出一個(gè)新對象即可