Vue 3 ref改变了DOM,但React性未改变

koaltpgm  于 2023-02-16  发布在  Vue.js
关注(0)|答案(3)|浏览(207)

下面的代码可以正常工作,当使用ref时,我可以看到预期的输出,但是当使用reactive时,我在DOM中看不到任何更改。如果I console.logtransaction,则在两种情况下数据都在那里。一旦作为变量的transaction发生更改,更改是否应该在两种情况下都不反映在DOM上?
我还在努力理解Vue3的组合API以及何时使用reactive和reactive,我的理解是,当处理对象时,使用reactive,而对原语类型使用ref。

使用ref,它工作:

<template>
   {{ transaction }}
</template>

<script setup>
import { ref } from 'vue'

let transaction = ref({})

const getPayByLinkTransaction = () => {
   axios({
      method: "get",
      url: "pay-by-link",
      params: {
         merchantUuid: import.meta.env.VITE_MERCHANT_UUID,
         uuid: route.params.uuid,
      },
   })
      .then((res) => {
         transaction.value = res.data
      })
      .catch((e) => {
         console.log(e)
      })
}

getPayByLinkTransaction()
</script>

使用React式不起作用:

<template>
   {{ transaction }}
</template>

<script setup>
import { reactive } from 'vue'

let transaction = reactive({})

const getPayByLinkTransaction = () => {
   axios({
      method: "get",
      url: "pay-by-link",
      params: {
         merchantUuid: import.meta.env.VITE_MERCHANT_UUID,
         uuid: route.params.uuid,
      },
   })
      .then((res) => {
         transaction = { ...res.data }
      })
      .catch((e) => {
         console.log(e)
      })
}

getPayByLinkTransaction()
</script>
lsmd5eda

lsmd5eda1#

哦,当你对reactive对象执行transaction = { ...res.data }时,你会覆盖它,就像你对其他变量引用一样。
起作用的是将以下内容分配给React对象:

Object.assign(transaction, res.data)

在内部,对象是一个Proxy,它使用抽象的getter和setter来触发更改事件并Map到相关的值,setter可以处理添加新属性。
另一方面,ref()不是代理,但它使用.value getter和setter执行相同的操作。
据我所知,reactive()的思想不是使任何单个对象成为React式的,而是将所有的引用集合在一个单独的React式对象中(有点类似于props对象),而ref()用于单个变量,在您的情况下,这意味着将其声明为:

const refs = reactive({transaction: {}})
refs.transaction = { ...res.data }

一般的建议似乎是选择一个并坚持使用它,大多数人似乎更喜欢ref(),最终归结为您是喜欢在脚本中编写transaction.value还是总是到处编写refs.transaction的烦恼。

lf5gs5x2

lf5gs5x22#

使用transaction = { ...res.data }时,变量transaction被一个新对象替换,并失去React性。
您可以通过直接更改data子属性或使用ref()代替reactivity()来省略它
这是可行的:

let transaction = ref({})
transaction.data = res.data;

查看Reactivity in Depth和Medium Ref() vs Reactive() in Vue 3上的这篇精彩文章,了解详细信息。
Playground
x一个一个一个一个x一个一个二个一个x一个一个三个一个

wgxvkvu9

wgxvkvu93#

由于被动事务是一个对象,请尝试使用Object.assign方法,如下所示:

Object.assign(transaction, res.data)

相关问题