问题记录
这里进行一个简单的记录。
今天发现一个小问题,在使用 ref 创建对象的对象无法重置为初始值。用了 kimi 和 deepseek 也没解决这个问题。最后灵光一闪,问题解决了
先看一下有问题的代码
const initPageInfo = {
pageNo: 1,
pageSize: 10,
total: 0,
}
const pageInfoRef = ref(initPageInfo)
在上面代码中进行了简单一个分页信息保存。在某些条件下,我希望重置这个分页信息,于是我尝试了以下的操作
pageInfoRef.value = {...initPageInfo}
原本以为这样就可以了,可是万万没想到,分页其实并没有被重置。于是我拿着我的信息问了 kimi 和 deepseek。他们告诉我要这么做
Object.assign(pageInfoRef.value, initPageInfo)
甚至还有更神的操作
pageInfoRef.value = JSON.parse(JSON.stringify(initPageInfo))
我尝试了他们说的第一个方案,没有效果。第二个神操作我没有试,但是我感觉应该不可以
解决方案
后来我忽然灵光一闪,下面是解决方案
在第一次对 pageInfoRef 进行初始化的时候需要更改一下方案
const pageInfoRef = ref({...initPageInfo})
原因分析(查看下面更新的内容)
这里我并没有分析出来具体的原因,可能与 ref 创建响应式对象的方式有一定的关系。
因为我在测试的过程中还尝试下面的方式,它是却是能进行正常响应式的。
我不理解这种原始的方式创建的对象和解构赋值得到的对象 {...initPageInfo} 是不是有什么本质的不同,导致 vue 不能正确的帮我创建响应式对象。或许需要看一下 vue 的相关文档或者是看一下相关源码了。暂时没有时间去深究这个问题。
pageInfoRef.value = {
pageNo: 1,
pageSize: 10,
total: 0,
}
2025年7月10日 更新
今日得闲,看了一下这个文章。找到了原因
直接使用
const pageInfoRef = ref(initPageInfo)
vue 会把 initPageInfo 这个对象变成响应式对象。
所以在后续中使用下面两种方式,看上去似乎没有改变 pageInfoRef,实际上是已经改变了。只是因为 initPageInfo 的内容已经被 pageInfoRef.value 修改过,所以只要是使用 initPageInfo 去修改 pageInfoRef.value 不论如何,都是无法回归初始值的
pageInfoRef.value = {...initPageInfo}
pageInfoRef.value = JSON.parse(JSON.stringify(initPageInfo))
验证方法
<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 函数中打印了 initPageInfo,会发现每次点上一页或者下一页的时候,都会改变 initPageInfo 这个对象的值
所以如果初始化 ref 的时候如果想让 pageInfoRef 还能被重置,那么在初始化的时候就要初始化一个完全脱离原来的引用对象。
比如使用 const pageInfoRef = ref({...initPageInfo}) 如此就可以让这个 pageInfoRef 响应式对象能被重置了
不过需要注意, {...initPageInfo} 只能处理简单的对象,如果是要处理复杂对象,就需要深度克隆。或者把 initPageInfo 变成一个函数,调用时返回出一个新对象即可