Skip to page content

useObjectUrl 组合式 API
v2.34+

useObjectUrl() composable 能把一个 Blob(包括 File)或 MediaSource 转换成一个响应式的对象 URL,你可以把它交给 <img>、<video>、QImg 或下载链接使用。对象 URL 一旦不再需要就必须被释放,否则只要页面还存活,浏览器就会一直把其底层数据保留在内存中;该 composable 会替你处理这件事:每当来源发生变化,以及当你的组件被销毁时,它都会释放该 URL。

它的典型用途包括:在上传之前预览已选择的文件、展示从 API 以 Blob 形式接收到的图片,或者播放媒体流。

TIP

在 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。

WARNING

一旦释放某个对象 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>