useObjectUrl() composable 能把一个 Blob(包括 File)或 MediaSource 转换成一个响应式的对象 URL,你可以把它交给 <img>、<video>、QImg 或下载链接使用。对象 URL 一旦不再需要就必须被释放,否则只要页面还存活,浏览器就会一直把其底层数据保留在内存中;该 composable 会替你处理这件事:每当来源发生变化,以及当你的组件被销毁时,它都会释放该 URL。
它的典型用途包括:在上传之前预览已选择的文件、展示从 API 以 Blob 形式接收到的图片,或者播放媒体流。
在 SSR 或 SSG 模式的服务端,objectUrl 始终保持为 null:那里既没有 URL.createObjectURL(),实际上也没有可指向的 Blob。
该 composable 也可以在 setup() 之外调用:在 boot 文件、store 或普通模块中。它在那里的工作方式完全相同,但不会自行释放 URL:完成后请把来源设为 null,或调用 revokeObjectUrl()。
语法
import { useObjectUrl } from 'quasar'
setup () {
const { objectUrl, revokeObjectUrl } = useObjectUrl(source)
// ...
}function useObjectUrl(
source?: MaybeRefOrGetter<Blob | MediaSource | null | undefined>
): {
objectUrl: Ref<string | null>
revokeObjectUrl: () => void
}source 可以是一个普通值、一个 Ref 或一个 getter 函数。普通值只读取一次。使用 Ref 或 getter 时,该 composable 会追踪它所读取的任何响应式状态:每当它产出一个不同的对象时,之前的 URL 会被释放,并创建一个新的 URL;如果产出 null 或 undefined,则会释放当前 URL 并让 objectUrl 保持为 null。一个重新执行但返回同一个对象的 getter 会保留原有 URL,因此一个已经用它显示出来的图片不会重新加载。
objectUrl 保存当前来源的对象 URL(blob:...)或 null。revokeObjectUrl() 会释放当前 URL 并彻底结束追踪;在组件内部你很少需要它,因为该 composable 会在组件销毁时自行释放 URL。
一旦释放某个对象 URL,从那一刻起它就无法再使用。任何仍然需要该数据的地方(尚未加载完成的 <img>、用户尚未点击的链接)都必须换用新的 objectUrl 值;不要留着旧值的副本继续用。
示例
用 useFilePicker composable 选择一张图片,并用 QImg 预览它。选择另一张图片会替换预览,并释放前一张图片的 URL:
<template>
<div class="q-pa-md">
<div class="row items-center q-gutter-sm">
<q-btn
color="primary"
push
icon="image"
label="Pick an image"
no-caps
@click="openFilePicker"
/>
<q-btn
v-if="objectUrl"
push
color="negative"
label="Clear"
no-caps
@click="image = null"
/>
</div>
<q-img
v-if="objectUrl"
:src="objectUrl"
fit="contain"
class="q-mt-md rounded-borders"
style="max-width: 300px; max-height: 200px"
/>
</div>
</template>
<script setup>
import { shallowRef } from 'vue'
import { useFilePicker, useObjectUrl } from 'quasar'
const image = shallowRef(null)
const { openFilePicker } = useFilePicker({
accept: 'image/*',
onChange(files) {
image.value = files[0]
}
})
const { objectUrl } = useObjectUrl(image)
</script>