dcloudio / uni-ui

基于uni-app的、全端兼容的、高性能UI框架
https://uniapp.dcloud.io/component/uniui/uni-ui.html
Apache License 2.0
1.88k stars 667 forks source link

uni-file-picker组件删除回显数据时会改变回显数据的结构 #912

Closed xiao-xiaozi closed 1 month ago

xiao-xiaozi commented 4 months ago

回显时的数据结构:

uploadFiles:[
{ name:'',extname:"",url:"https://tse3-mm.cn.bing.net/th/id/OIP-C.Md86Wi2EYiKHNPldRZiD4gHaEo?w=286&h=180&c=7&r=0&o=5&pid=1.7",id:3 },
{ name:'',extname:"",url:"https://tse1-mm.cn.bing.net/th/id/OIP-C.Zte3ljd4g6kqrWWyg-8fhAHaEo?w=286&h=180&c=7&r=0&o=5&pid=1.7",id:2 },
{ name:'',extname:"",url:"https://tse4-mm.cn.bing.net/th/id/OIP-C.GC_ugX-TzPVR26SSxI1kZwHaE9?w=267&h=180&c=7&r=0&o=5&pid=1.7",id:1 },
]

触发一次删除后的数据结构

[
{ cloudPath:undefined, extname:"", fileID:undefined, fileType:undefined, image:undefined, name:"", path:"https://tse3-mm.cn.bing.net/th/id/OIP-C.Md86Wi2EYiKHNPldRZiD4gHaEo?w=286&h=180&c=7&r=0&o=5&pid=1.7",size:undefined,status:undefined, url:"https://tse3-mm.cn.bing.net/th/id/OIP-C.Md86Wi2EYiKHNPldRZiD4gHaEo?w=286&h=180&c=7&r=0&o=5&pid=1.7",uuid:undefined }
// .....
]

查看组件源码发现是触发delete事件时,执行setEmit方法,触发backObject导致的数据结构变化

部分源码:


// ...

/**
 * 删除文件
 * @param {Object} index
 */
delFile(index) {
    this.$emit('delete', {
        index,
        tempFile: this.files[index],
        tempFilePath: this.files[index].url
    })
    this.files.splice(index, 1)
    this.$nextTick(() => {
        this.setEmit()
    })

/**
 * 获取文件名和后缀
 * @param {Object} name
 */
getFileExt(name) {
    const last_len = name.lastIndexOf('.')
    const len = name.length
    return {
        name: name.substring(0, last_len),
        ext: name.substring(last_len + 1, len)
    }

/**
 * 处理返回事件
 */
setEmit() {
    let data = []
    if (this.returnType === 'object') {
        data = this.backObject(this.files)[0]
        this.localValue = data?data:null
    } else {
        data = this.backObject(this.files)
        if (!this.localValue) {
            this.localValue = []
        }
        this.localValue = [...data]
    }
    // #ifdef VUE3
    this.$emit('update:modelValue', this.localValue)
    // #endif
    // #ifndef VUE3
    this.$emit('input', this.localValue)
    // #endif
},

/**
 * 处理返回参数
 * @param {Object} files
 */
backObject(files) {
    let newFilesData = []
    files.forEach(v => {
        newFilesData.push({
            extname: v.extname,
            fileType: v.fileType,
            image: v.image,
            name: v.name,
            path: v.path,
            size: v.size,
            fileID:v.fileID,
            url: v.url,
            // 修改删除一个文件后不能再上传的bug, #694
      uuid: v.uuid,
      status: v.status,
      cloudPath: v.cloudPath
        })
    })
    return newFilesData
}

// ...

这里的数据结构改变会导致原存放在回显数据里面的业务字段丢失,例如此次回显数据的id字段。

两个问题

  1. 此处数据结构变更是否应该保留原有字段?期望应该是的
  2. delete事件在触发删除之前就已经抛出$emit('delete),这里会导致在父组件在响应删除事件时拿到的数据时删除前的
xiao-xiaozi commented 4 months ago

补充第二点问题的期望:应该是删除后再抛出delete事件吧。

GRCmade commented 1 month ago

你好,这么做是为了与unicloud数据结构对齐,如果对你造成问题可以尝试在使用前验证

xiao-xiaozi commented 1 month ago

你好,这么做是为了与unicloud数据结构对齐,如果对你造成问题可以尝试在使用前验证

请问是不是可以理解为这个uni-file-picker组件只能在使用unicloud的情况下使用

GRCmade commented 1 month ago

你好,这么做是为了与unicloud数据结构对齐,如果对你造成问题可以尝试在使用前验证

请问是不是可以理解为这个uni-file-picker组件只能在使用unicloud的情况下使用

不是的,这只是放回时的数据不同而已