3.5 Browser – useFileDialog
https://vueuse.org/core/useFileDialog/
作用
打开一个文件选择对话框
官方示例
import { useFileDialog } from '@vueuse/core'
const { files, open, reset } = useFileDialog()
这个函数是可以传递参数的,官方示例没有写。
export interface UseFileDialogOptions extends ConfigurableDocument {
/**
* @default true
* 是否可以多选
*/
multiple?: boolean
/**
* @default '*'
* 可以选择的类型
*/
accept?: string
/**
* Select the input source for the capture file.
* capture属性只在移动设备上受支持,因此,当在桌面浏览器上打开时,它将被忽略。用来打开摄像头。
* @see [HTMLInputElement Capture](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/capture)
*/
capture?: string
}
源码分析
主要思路就是创建一个 input
,这个标签的type
为file
时,可以调起文件对话框。open
事件时,触发input
的点击事件。
由于这个input
并没有插入到页面中,所以是不可见的。
export function useFileDialog(options: UseFileDialogOptions = {}): UseFileDialogReturn {
const {
document = defaultDocument,
} = options
const files = ref<FileList | null>(null)
let input: HTMLInputElement | undefined
/**
* 创建一个input元素,当用户选择了文件,把文件赋值给files
*/
if (document) {
input = document.createElement('input')
input.type = 'file'
input.onchange = (event: Event) => {
const result = event.target as HTMLInputElement
files.value = result.files
}
}
/**
* 调用open的时候,就是触发input的click事件。前置操作都是赋值。
*/
const open = (localOptions?: Partial<UseFileDialogOptions>) => {
if (!input)
return
const _options = {
...DEFAULT_OPTIONS,
...options,
...localOptions,
}
input.multiple = _options.multiple!
input.accept = _options.accept!
if (hasOwn(_options, 'capture'))
input.capture = _options.capture!
input.click()
}
const reset = () => {
files.value = null
if (input)
input.value = ''
}
return {
files: readonly(files),
open,
reset,
}
}