vue3何时失去响应性

情况一:当对象属性里面的值在template进行计算时

根据vue文档,当我们设置

<template>
  <button @click="increment">
    {{ object.foo + 1 }}
  </button>
</template>
<script setup>
import { ref } from 'vue'

const object = { foo: ref(1) }

function increment() {
  object.foo.value++
}
</script>

得到的结果是

 点击后会发现,数据改变了,但是视图不会变

文档中所说:

请注意,仅当 ref 是模板渲染上下文的顶层属性时才适用自动“解包”。 例如, foo 是顶层属性,但 object.foo 不是

意思大概是,把一个对象比喻成树,只有树顶端的值才会被解包。这个树就是ref

文档中也说明了解决方法

解决方法一

将foo进行解构就可以了,把foo作为顶层属性

<template>
  <button @click="increment">
     {{ foo + 1 }} 
  </button>
</template>

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

const object = { foo: ref(1) }

const { foo } = object

function increment() {
    object.foo.value++
}
</script>

 解决方法二

由文档的原理可以明白,只要我们吧object作为ref的顶层属性,也可以实现

<template>
  <!-- <router-view /> -->
  <button @click="increment">
    {{ obj.foo + 1 }}
  </button>
</template>

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

const obj = ref({
  foo: 0
})

function increment() {
  obj.value.foo++
}
</script>

情况二:方法二中如果进行结构会不会失去响应性呢?

        

<template>
  <!-- <router-view /> -->
  <button @click="increment">
    {{ foo }}
  </button>
</template>

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

const obj = ref({
  foo: 0
})
let { foo } = obj.value
foo++
function increment() {
  foo++
  console.log(foo)
}
</script>

结果确实会失去响应性

而且vue插件中foo的值不会再监听到变化,但打印的时候会改变

打印时

vue插件看到的

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Vue 使用 `JSON.parse(JSON.stringify(obj))` 来深拷贝响应式数据。但是,这种方法会丢失对象的响应质,因此需要使用 Vue.set(target, key, value) 或 Vue.delete(target, key) 来重新设置响应质。 如果数据量很大,建议使用第三方库进行深拷贝,如 lodash 中的 _.cloneDeep() 方法。 ### 回答2: 在Vue中,拷贝响应式数据可以使用`JSON.parse(JSON.stringify())`的方法。 Vue中的响应式数据是通过Vue响应式系统进行管理的,当数据发生变化时,相关的视图会自动更新。然而,有时我们需要对响应式数据进行拷贝,这可能是为了进行深层次的修改或者为了保留数据的原始状态等目的。 在拷贝响应式数据时,直接使用常见的拷贝方法(如`Object.assign()`、`slice()`等)可能会导致新的对象失去响应式功能,也就是说对新对象的修改不会触发相关视图的更新。 为了避免这个问题,我们可以使用`JSON.parse(JSON.stringify())`的方法来进行拷贝。该方法会将对象转换为字符串,然后再将字符串转换回对象,这样可以得到一个全新的对象,而且这个对象不再具有响应式功能,但可以进行普通的数据操作。 示例代码如下: ```javascript var originalData = { name: '张三', age: 18 }; var copiedData = JSON.parse(JSON.stringify(originalData)); copiedData.name = '李四'; console.log(originalData); // 输出:{ name: '张三', age: 18 } console.log(copiedData); // 输出:{ name: '李四', age: 18 } ``` 需要注意的是,使用`JSON.parse(JSON.stringify())`进行拷贝时,只能处理简单的对象或数组,对于复杂的对象(例如包含函数、正则表达式等),可能会出现意料之外的结果。因此,在进行拷贝操作时,需要谨慎选择合适的方法来保证数据的完整和正确
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值