Skip to content

Commit

Permalink
feat(useObjectUrl): new function (#1763)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelhue committed Jul 6, 2022
1 parent 092cb19 commit 6ccd094
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/components/index.ts
Expand Up @@ -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'
Expand Down
1 change: 1 addition & 0 deletions packages/core/index.ts
Expand Up @@ -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'
Expand Down
22 changes: 22 additions & 0 deletions 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<UseObjectUrlProps>({
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)
}
},
})
30 changes: 30 additions & 0 deletions packages/core/useObjectUrl/demo.vue
@@ -0,0 +1,30 @@
<script setup lang="ts">
import { shallowRef } from 'vue-demi'
import { useObjectUrl } from '@vueuse/core'
const file = shallowRef()
const url = useObjectUrl(file)
const onFileChange = (e: Event) => {
const target = e.target as HTMLInputElement
const files = target.files
file.value = files && files.length > 0 ? files[0] : undefined
}
</script>

<template>
<div>
<note class="mb-1">
Select file:
</note>
<input type="file" @change="onFileChange">

<note class="mt-4 mb-1">
Object URL:
</note>
<code>
<a v-if="url" :href="url" target="_blank">{{ url }}</a>
<span v-else>none</span>
</code>
</div>
</template>
41 changes: 41 additions & 0 deletions 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
<script setup>
import { useObjectUrl } from '@vueuse/core'
import { shallowRef } from 'vue'
const file = shallowRef()
const url = useObjectUrl(file)
const onFileChange = (e) => {
file.value = event.target.files[0]
}
</script>

<template>
<input type="file" @change="onFileChange" />

<a :href="url">Open file</a>
</template>
```

## Component Usage

```html
<template>
<UseObjectUrl v-slot="url" :object="file">
<a :href="url">Open file</a>
</UseObjectUrl>
</template>
```
35 changes: 35 additions & 0 deletions 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<Blob | MediaSource | undefined>) {
const url = ref<string | undefined>()

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)
}

0 comments on commit 6ccd094

Please sign in to comment.