js選擇文件上傳
之前傳統(tǒng)的選擇文件方式是給一個(gè)input標(biāo)簽點(diǎn)擊上傳,然后美化一下UI咆瘟。后面出了一些新的API嚼隘,可以用js方式來處理選擇文件這個(gè)操作。
以下是一些相關(guān)的API:
Window.showSaveFilePicker()
Window.showOpenFilePicker()
Window.showDirectoryPicker()
Window.showModalDialog()(已刪除)
使用的時(shí)候需要查詢一下兼容性袒餐,比如在pc瀏覽器模擬器里可以上傳飞蛹,但是在移動(dòng)端瀏覽器上卻不會出現(xiàn)選擇文件的彈窗,需要寫一個(gè)polyfill,對于不能調(diào)用showOpenFilePickerPolyfill方法的用傳統(tǒng)方式
async showOpenFilePickerPolyfill (options = [{}]) {
if (!Array.isArray(options)) {
options = [options]
}
return new Promise((resolve, reject) => {
const input = document.createElement('input')
input.type = 'file'
const accept = [
...options.map((option) => option.mimeTypes || []),
...options.map((option) => option.extensions || [])
].join()
input.multiple = options[0].multiple || false
input.accept = accept || ''
input.style.display = 'none'
document.body.append(input)
const _reject = () => cleanupListenersAndMaybeReject(reject)
const _resolve = (value) => {
if (typeof cleanupListenersAndMaybeReject === 'function') {
cleanupListenersAndMaybeReject()
}
resolve(value)
}
const cleanupListenersAndMaybeReject =
options[0].legacySetup &&
options[0].legacySetup(_resolve, _reject, input)
const cancelDetector = () => {
window.removeEventListener('focus', cancelDetector)
input.remove()
}
input.addEventListener('click', () => {
window.addEventListener('focus', cancelDetector)
})
input.addEventListener('change', () => {
window.removeEventListener('focus', cancelDetector)
input.remove()
_resolve(input.multiple ? Array.from(input.files) : input.files[0])
})
if ('showPicker' in HTMLInputElement.prototype) {
input.showPicker()
} else {
input.click()
}
})
}
supported () {
if (typeof window.self === 'undefined') {
return false
}
if ('top' in window.self && window.self !== window.top) {
try {
// eslint-disable-next-line no-unused-expressions
window.top.location + ''
} catch (e) {
return false
}
return false
} else if ('showOpenFilePicker' in window.self) {
return 'showOpenFilePicker'
}
return false
}
其他API polyfill請參考:
https://github.com/GoogleChromeLabs/browser-fs-access
裁剪工具
可能通過搜索出現(xiàn)最多的是vue-copper灸眼,經(jīng)過一通操作后卧檐,發(fā)現(xiàn)問題很多,并且卡頓焰宣,后面更換了vue-advanced-cropper,感覺還挺不錯(cuò)的霉囚,可以滿足要求,移動(dòng)順暢匕积。這后面的操作就比較簡單了盈罐,就是通過使用這個(gè)插件,獲取相應(yīng)的blob或者base64來上傳到服務(wù)器
async handleChangeAvatar () {
var src = ''
if (this.supported()) {
const arrFileHandle = await window.showOpenFilePicker(this.options)
src = await this.handleFiletoBlob(arrFileHandle)
} else {
const blob = await this.showOpenFilePickerPolyfill(this.options)
src = URL.createObjectURL(blob)
}
this.option.img = src
this.showCopper = true
this.$nextTick(() => {
const ele = document.querySelector('#app')
ele.appendChild(this.$refs.showCopper)
})
this.showAvatar = false
this.showSheet = false
}
獲取圖像
const { canvas } = this.$refs.cropper.getResult()