Vue3 Ref 對象無法重置的問題

問題記錄

這里進(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è)新對象即可

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容