diff --git a/packages/components/index.ts b/packages/components/index.ts index 5ce12f9f29d..a45a339327e 100644 --- a/packages/components/index.ts +++ b/packages/components/index.ts @@ -32,6 +32,7 @@ export * from '../core/useMouseInElement/component' export * from '../core/useMousePressed/component' export * from '../core/useNetwork/component' export * from '../core/useNow/component' +export * from '../core/useObjectUrl/component' export * from '../core/useOffsetPagination/component' export * from '../core/useOnline/component' export * from '../core/usePageLeave/component' diff --git a/packages/core/index.ts b/packages/core/index.ts index bebfc8af531..c6be4d7f438 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -72,6 +72,7 @@ export * from './useMutationObserver' export * from './useNavigatorLanguage' export * from './useNetwork' export * from './useNow' +export * from './useObjectUrl' export * from './useOffsetPagination' export * from './useOnline' export * from './usePageLeave' diff --git a/packages/core/useObjectUrl/component.ts b/packages/core/useObjectUrl/component.ts new file mode 100644 index 00000000000..135b22fd72f --- /dev/null +++ b/packages/core/useObjectUrl/component.ts @@ -0,0 +1,22 @@ +import { defineComponent, toRef } from 'vue-demi' +import { useObjectUrl } from '@vueuse/core' + +export interface UseObjectUrlProps { + object: Blob | MediaSource | undefined +} + +export const UseObjectUrl = defineComponent({ + name: 'UseObjectUrl', + props: [ + 'object', + ] as unknown as undefined, + setup(props, { slots }) { + const object = toRef(props, 'object') + const url = useObjectUrl(object) + + return () => { + if (slots.default && url.value) + return slots.default(url) + } + }, +}) diff --git a/packages/core/useObjectUrl/demo.vue b/packages/core/useObjectUrl/demo.vue new file mode 100644 index 00000000000..8b66b712fdb --- /dev/null +++ b/packages/core/useObjectUrl/demo.vue @@ -0,0 +1,30 @@ + + + diff --git a/packages/core/useObjectUrl/index.md b/packages/core/useObjectUrl/index.md new file mode 100644 index 00000000000..8962710fd84 --- /dev/null +++ b/packages/core/useObjectUrl/index.md @@ -0,0 +1,41 @@ +--- +category: Browser +--- + +# useObjectUrl + +Reactive URL representing an object. + +Creates an URL for the provided `File`, `Blob`, or `MediaSource` via [URL.createObjectURL()](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL) and automatically releases the URL via [URL.revokeObjectURL()](https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL) when the source changes or the component is unmounted. + +## Usage + +```html + + + +``` + +## Component Usage + +```html + +``` diff --git a/packages/core/useObjectUrl/index.ts b/packages/core/useObjectUrl/index.ts new file mode 100644 index 00000000000..2e03e7a1795 --- /dev/null +++ b/packages/core/useObjectUrl/index.ts @@ -0,0 +1,35 @@ +import { readonly, ref, unref, watch } from 'vue-demi' +import { tryOnScopeDispose } from '@vueuse/shared' +import type { MaybeRef } from '@vueuse/shared' + +/** + * Reactive URL representing an object. + * + * @see https://vueuse.org/useObjectUrl + * @param object + */ +export function useObjectUrl(object: MaybeRef) { + const url = ref() + + const release = () => { + if (url.value) + URL.revokeObjectURL(url.value) + + url.value = undefined + } + + watch( + () => unref(object), + (newObject) => { + release() + + if (newObject) + url.value = URL.createObjectURL(newObject) + }, + { immediate: true }, + ) + + tryOnScopeDispose(release) + + return readonly(url) +}