如何使响应性与从构造函数开始的承诺一起工作?



我有一个类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>

相关内容

  • 没有找到相关文章

最新更新