我有一个类Thing
,它的构造函数启动异步fetch
操作。当fetch
完成时,结果被分配给Thing
对象上的一个字段:
class Thing {
constructor() {
this.image = null
this.load()
}
async load() {
const response = await fetch('https://placekitten.com/200/300')
const blob = await response.blob()
this.image = await createImageBitmap(blob)
}
}
我在Vue
组件中使用thing.image
。问题是,当Promise
解析时,Vue不会拾取image
中的更改。我想我理解为什么会这样:在构造函数中,this
指的是原始的Thing
,而不是Vue的响应式代理包装器。因此,对this.image
的赋值最终绕过了代理。
如果我将load
调用移出构造函数,那么load
函数中的this
就会引用响应代理。但这使得我的Thing
类更难使用。
有更好的方法来处理这个问题吗?
最小示例(Vue playground链接):
<script setup>
import { reactive } from 'vue'
class Thing {
constructor() {
this.image = null
this.load() // This does not trigger reactivity.
}
async load() {
const response = await fetch('https://placekitten.com/200/300')
const blob = await response.blob()
this.image = await createImageBitmap(blob)
}
}
const thing = reactive(new Thing())
// thing.load() // This triggers reactivity as expected.
</script>
<template>
<p v-if="thing.image">
Image size is {{thing.image.width}}×{{thing.image.height}}
</p>
<p v-if="!thing.image">
Loading...
</p>
</template>
将class属性定义为ref
<script setup>
import { reactive, ref } from 'vue'
class Thing {
constructor() {
this.image = ref(null)
this.load()
}
async load() {
const response = await fetch('https://placekitten.com/200/300')
const blob = await response.blob()
this.image.value = await createImageBitmap(blob)
}
}
const thing = reactive(new Thing())
// thing.load() // This triggers reactivity as expected.
</script>
<template>
<p v-if="thing.image">
Image size is {{thing.image.width}}×{{thing.image.height}}
</p>
<p v-if="!thing.image">
Loading...
</p>
</template>