uniapp uni-file-picker 上传踩坑

10,449 阅读2分钟

在使用uni-file-picker组件的时候,遇到了奇怪的问题。

一、上传任意数量文件,@select事件绑定的方法里,输出v-model绑定的值,都为空。

二、连续删除两个文件,@delete事件绑定的方法,输出v-model绑定的值,此时不为空,而且是删除文件之前的值。(比如上传了三个文件,连续删除两个,值的length为2)

方式一(后面发现有问题): v-model绑定的值与实际不一致,新建一个数组FileList,选择、删除文件时触发对应事件,对FileList数组增减操作。

<uni-file-picker
    ref="files"
    v-model="fileList"
    :auto-upload="false"
    @select="selectFile"
    @delete="deleteFile">
</uni-file-picker>

选择文件时,触发select事件,事件绑定方法返回tempFiles, tempFilePaths

const selectFile = (res) => {
        let {tempFiles, tempFilePaths} = res

        tempFiles.forEach(ele => {
                let {name, url, uuid, file} = ele
                data.FileList.push({
                        name,
                        url,
                        file,
                        uuid,
                })
        })
}

把file,uuid以及其他信息一起存入FileList

1678760477.png

删除文件时,触发delete事件,根据返回值里file的uuid,删除FileList对应的数据

const deleteFile = async (res) => {
    console.log(res)
    let {tempFile: {uuid}} = res
    let Index = null
    let tar = data.FileList.filter((file, index) => {
        if (file.uuid == uuid) {
            Index = index
        }
    })[0]
    if (typeof Index == 'number') {
        data.FileList.splice(Index, 1)
    }
}

删除一张图片,正常执行,删除两张图片,这时问题出现了,看一下两次触发事件的返回值

第一次删除 1678773883(1).png 第二次删除 1678773839(1).png 第二次触发事件的返回值里,少了uuid,所以在FileList中查不到,删除的是哪一张图片

0.jpg

向同事请教之后用另一种方法(方式二)

方式二:触发select、delete事件时,调用服务端上传图片、删除图片的接口,再调用获取图片list的接口,uni-file-picker组件v-model重新赋值

<uni-file-picker
    ref="files"
    v-model="fileList"
    :auto-upload="false"
    @select="selectFileNew"
    @delete="deleteFileNew">
</uni-file-picker>

触发select事件

const selectFileNew = (res) => {
    // console.log(res)
    let {tempFiles} = res
    let files = tempFiles.map(ele => {
        let {file} = ele
        return{
            name: 'files',
            file,
        }
    })

    let {baseURL} = config
    uni.uploadFile({
        header: {
            'token': uni.getStorageSync('token')
        },
        url: `${baseURL}/upload`, // 上传图片的接口
        files,
        formData: {
            // 服务端上传接口要求的其他参数
            btype: 'xxx',
            bid: 'bid',
        },
        success: async (uploadFileRes) => {
            // 获取图片list
            getPicList()
        }
    })
}

获取图片list

const getPicList = async () => {
    // 获取图片list的接口
    const {datas} = await cquery('attachment', {btype: 'xxx', bid: 'bid'})
    // 更新v-model绑定值
    data.fileList = datas.map(ele => {
        let {uuid, filepath, filetype, filename, bid} = ele
        return {
            uuid,
            url: backImgSrc(uuid, '1'),
            extname: filetype,
            name: filename,
        }
    })
}

触发delete事件

const deleteFileNew = async (res) => {
    let {tempFile} = res
    // 删除图片接口
    const {datas, status, msg} = await fileDelete(tempFile.uuid)
    let state = status == 200 ? 'success' : 'error'
    uni.showToast({
        title: msg,
        duration: 2000,
        icon: state
    })
    // 获取图片list
    getPicList()
}

没有想到比较好的做法,在这抛砖引玉,最后,这个问题在DCloud的问答社区看到前面有人提出这问题,但一直没有修复,真心希望官方能重视一下。