uTools开发最佳实践-更加丝滑的文件上传

185 阅读1分钟

uTools中,是要web的文件上传组件,会导致主窗口隐藏,并且web的上传组件需要<input type="file"></input>标签,比较麻烦,本文介绍的方法,直接js调用即可,方便快捷。

代码

首先,创建preload.js文件,并在plugin.json指定preload字段 在preload.js中加入:

const {readFile} = require('fs');
const {basename} = require('path');

function readFileAsync(path) {
    return new Promise((resolve, reject) => {
        readFile(path, (err, data) => {
            if (err) {
                reject(err);
                return;
            }
            resolve(data);
        })
    })
}

/**
 * 获取一个文件
 * @param options {options: {
 *     title?: string,
 *     defaultPath?: string,
 *     buttonLabel?: string,
 *     filters?: { name: string, extensions: string[] }[],
 *     properties?: Array<'openFile' | 'openDirectory' | 'multiSelections' | 'showHiddenFiles' | 'createDirectory' | 'promptToCreate' | 'noResolveAliases' | 'treatPackageAsDirectory' | 'dontAddToRecent'>,
 *     message?: string,
 *     securityScopedBookmarks?: boolean
 *   }} 参数
 * @return {Promise<Array<File>>} 返回文件对象
 */
async function openFile(options) {
    const paths = utools.showOpenDialog(options);
    const files = [];
    for (const path of paths) {
        const data = await readFileAsync(path);
        const name = basename(path);
        const type = 'application/octet-stream';
        const blob = new Blob([data], { type: type });
        const file = new File([blob], name, { type: type });
        // 给文件加入path属性
        file.path = path;
        files.push(file);
    }
    return files;
}

window.preload = {
    openFile
}

如果你是要ts开发,可以在vite-env.d.ts中加入函数定义:

interface OpenFileOption {
    title ?: string,
    defaultPath ?: string,
    buttonLabel ?: string,
    filters ?: { name: string, extensions: string[] }[],
    properties ?: Array < 'openFile' | 'openDirectory' | 'multiSelections' | 'showHiddenFiles' | 'createDirectory' | 'promptToCreate' | 'noResolveAliases' | 'treatPackageAsDirectory' | 'dontAddToRecent' >,
    message ?: string,
    securityScopedBookmarks ?: boolean
}

interface Window {
    preload: {
        /**
         * 打开一个文件,并返回blob对象
         * @param options 参数
         * @return 返回文件列表
         */
        openFile(options: OpenFileOption): Promise<Array<File>>
    }
}

使用

window.preload.openFile({
    title: '选择图片',
    filter: [{
        name: '图片',
        extensions: ['jpg', 'png', 'git', 'jpeg', 'webp']
    }]
}).then(files => {
    // 自己的逻辑,files就是选择的File数组
})