如何在不失去反应性的情况下更新反应性对象(vue3合成API)

moo*_*ris 3 javascript vue.js

我尝试更新反应性对象,但反应性丢失。

如何解决这个问题呢?

const obj = reactive({ id:0 , name: "Tom" })


const updateObj = { id:1 , name: "Bob" }

Object.keys(updateObj).forEach(key => {
   obj[key] = updateObj[key]
 })


console.log( isRef( obj.id ) )  // => false

Run Code Online (Sandbox Code Playgroud)

Nin*_*ina 6

实际上,当涉及到反应性时,您的示例应该有效。与其迭代键,简单地使用 可能是一个更好的主意Object.assign(obj, updateObj),但您的方法也应该有效。

但是,您似乎对反应性和函数有一个轻微的误解isRefisRef不检查给定的参数是否是反应性的,而是特别检查它是否是一个ref对象(请参阅Vue 文档中的本节)。还有一个被调用的函数isReactive可以专门检查对象是否是对象reactive(请参见此处)。请注意,对于响应式对象的属性,这也不会返回 true。

我创建了一个小示例,它应该说明这两种方法之间的区别。它还表明,即使isRefisReactive函数都返回 ,反应性仍然有效false

<script setup>
import { computed, reactive, ref, isReactive, isRef } from 'vue';
  
const obj = reactive({ id: 0 , name: "Tom" })
const realRef = ref('foo')

const isRefOrReactive = computed(() => ({
  objRef: isRef(obj),
  objReactive: isReactive(obj),
  objIdRef: isRef(obj.id),
  objIdReactive: isReactive(obj.id),
  refRef: isRef(realRef),
  refReactive: isReactive(realRef)
}))

const updateObject = () => {
  const updateObj = { id: 1 , name: "Bob" }
  Object.keys(updateObj).forEach(key => {
    obj[key] = updateObj[key]
  })
  // Object.assign(obj, updatedObj)
}
</script>

<template>
  <pre>{{ obj }}</pre>
  <pre>{{ obj.name }}</pre>
  <pre>{{ isRefOrReactive }}</pre>
  <button @click="updateObject">
    Swap data
  </button>
</template>
Run Code Online (Sandbox Code Playgroud)