情况一:当对象属性里面的值在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插件看到的