Vue3整合Pinia,懂行的大佬进来帮忙看下,为什么 重新在将store的属性设置为 reactive({})不生效?-灵析社区

生成头像

本来是向搞个在线项目 方便大家大家理解,但是试了几个云ide平台都太卡了,不好用就没搞。 ## 问题 需求场景是这样的 有一个pinia Store(studentStore),这个store内部定义了一个 let address = reactive({}) . 然后 有一个方法 resetAddress 方法会重新将 address变量指向另外一个新的响应式代理对象。 export const useStudentStore = defineStore('student', () => { //只会被执行一次 console.log("studentStore的defineStore函数执行") const name = ref("zhangsan") let address = reactive({}) let studentInfo = reactive({}) const changeCity = function (city) { address.city = city } const resetAddress = function () { //注意这里将 address 指向一个新的响应式代理对象 address = reactive({}) } const resetStudentInfo = function () { studentInfo = reactive({}) } return { name, address, studentInfo, resetStudentInfo, changeCity, resetAddress, } }) 在组件A中 执行 useStudentStore 函数得到studentStore. 然后 在组件A中显示studentStore的address属性。 组件A中有一个按钮,这个按钮随机生成 字符串1 和字符串2, 他们分别作为 属性名和属性值 被添加到address身上。 这个按钮还会生成一个随机数字,数字大于17的时候就会 调用resetAddress方法。 我们看到的效果就是 点击按钮---》addres新增了一个属性---》再次点击---》再次新增一个属性---》突然某次生成的随机数大于17,执行resetAddress方法。 resetAddres方法内部会将 defineStoree函数的第二个参数函数中的 address 指向一个新的响应式代理对象, 这个新的响应式代理对象显然没有任何属性。 对于组件A 他模板中渲染的仍然还是之前的对象。 这是为什么 这是TestPinia.vue {{ studentStore.name }} address: {{ studentStore.address }} studentInfo: {{ studentStore.studentInfo }} 点击 import {useStudentStore} from '@/store/student.js' import {ref, reactive, onMounted, inject, toRef, toRefs} from "vue"; import {storeToRefs} from "pinia"; import Constants from "@assets/js/Constants.js"; const $utils = inject(Constants.$utilsSymbol); const studentStore = useStudentStore(); // const { // name, // address, // studentInfo // } = storeToRefs(studentStore); const {changeCity, resetCity, resetStudentInfo} = studentStore; function handleClick() { let propName = $utils.randomString(5); let propvalue = $utils.randomString(3); studentStore.address[propName] = propvalue; let random = $utils.GetRandomNum(10, 20); if (random > 17) { console.log("resetCity"); resetCity(); } } ## 问题 1 . resetAddres方法内部会将 defineStoree函数的第二个参数函数中的 address 指向一个新的响应式代理对象, 这个新的响应式代理对象显然没有任何属性。 对于组件A 他模板中渲染的仍然还是之前的对象。 这是为什么 2. 应该不会有这种 resetAddress内部 重新将 address指向一个新的响应式代理对象的需求吧? 我之所以会这样写 是因为 有一种场景: 把后端返回的一个对象放置到store的addres中,但是不知道 返回的这个对象有哪些属性。 所以我无法通过address.xxPropName的形式给address设置值 ,而是用了 Object.assign(后端返回对象, address)。 在需要清空address对象的时候 就写出了这种 resetAddress的代码。 问题有描述清除么? * * * ## 补充问题 我还有一个地方不明白。 const person = ref({ name: "zhangsan", age: 12, }) console.log("person", person) ref的是一个对象,等价于这个对象 先 reactive( {} )得到一个响应式代理对象Proxy,然后RefImpl对象的value等于这个响应式代理对象. 就是i下面这种结构 ![image.png](https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250103/6ccc0270b2237bb22587378777a09aef.png) 如果执行 代码 ` person.value = {}` 会出现什么现象? 我的理解: person是RefImpl, 将他的value指向一个空对象,不再是之前的响应式代理对象。 实际现象:如下图,value还是一个响应式代理对象,只不过这个Proxy代理对象的target目标对象是空对象 ![image.png](https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250103/1d9f3757741cb6bfd401666a14c9f579.png) 问题: 这是为什么?怎么做到的? 有相关的参考资料或者源码么?

阅读量:325

点赞量:12

问AI
如果想要直接替换整个对象 的话,应该使用 "ref" 而不是 "reactive",具体可查看官方文档"reactive() 的局限性" (https://link.segmentfault.com/?enc=CIouKTNud7B31S7OvgVUhw%3D%3D.Wy%2BtpuzZvCOmMIMHsp0K39F0mzOg43UkBgDgyEzwGez8Vqhdzh1DwOzsHp8S6kSu5NOnv2NkGKUEbsil7SnNo%2F2tCqVl3kqK7pq1uSv3soCTleJ5U7EMAAzGPNde63o7)中的描述 «不能替换整个对象 :由于 Vue 的响应式跟踪是通过属性访问实现的,因此我们必须始终保持对响应式对象的相同引用。这意味着我们不能轻易地“替换”响应式对象,因为这样的话与第一个引用的响应性连接将丢失:let state = reactive({ count: 0 }) // 上面的 ({ count: 0 }) 引用将不再被追踪 // (响应性连接已丢失!) state = reactive({ count: 1 }) » 正确写法如下: const address = ref({}); function resetAddress() { address.value = {}; }