简体   繁体   English

重命名/删除上传的文件 - Vue.js

[英]Renaming/removing uploaded files - Vue.js

The requirement is to rename the files before uploading it to the system.要求是在将文件上传到系统之前重命名文件。 So I tired using v-model but failed.所以我厌倦了使用 v-model 但失败了。 So I came up with the following which is working great just that I cannot retain my input text value.因此,我想出了以下方法,它工作得很好,只是我无法保留我的输入文本值。 The preventdefault isn't working. preventdefault不起作用。

Here I uploaded 3 images and rename them as First, Second and Third.在这里,我上传了 3 张图片并将它们重命名为第一、第二和第三。

<div>
    <input type="file" @change="addFile" multiple>Choose file
</div>

<div v-if="selectedFiles && selectedFiles.length>0">
       <div v-for="(item, index) in selectedFiles">
            <span>{{ item.name }}</span>
            <input type="text" v-model="" placeholder="Rename File" @change="renameFile(item,event)"/>
            <button @click="removeFile(event,item,index)"></button>                                    
        </div>
 </div>   
 <button @click="uploadDrawings">Upload Files</button>                                        
data: {
      selectedFiles: [],
      renameFiles: [],
      finalFiles: [], 
},
methods: {

    addFile(event) {
        _.each(Array.from(event.target.files), function (file) {

            var existed = _.find(app.selectedFiles, function (item) {
                return item.name == file.name;
            });

            if (!existed) {
                app.selectedFiles.push(file);
            }
        });
    },
    renameFile(item, event) {
        if (app.renameFiles.filter(x => x.oldName == item.name).length > 0) {
            var objIndex = app.renameFiles.findIndex(x => x.oldName == item.name);
            app.renameFiles[objIndex].newName = event.target.value;
        }
        else {
            app.renameFiles.push({
                oldName: item.name,
                newName: event.target.value
            })
        }
    },
    removeFile(e,item, index) {
        e.preventDefault(); // while removing an item, the text value changes.
        app.selectedFiles.splice(index, 1);
        var objIndex = app.renameFiles.findIndex(x => x.oldName == item.name);
        app.renameFiles.splice(objIndex, 1);
    },

    uploadDrawings() {
       app.isLoading = true;
       if (app.selectedFiles.length == 0) {
         return;
     }

     _.each(app.selectedFiles, function (item) {
          var blob = item.slice(0, item.size, 'image/jpg');
          var name = app.renameFiles.filter(x => x.oldName == item.name);
          app.finalFiles.push(new File([blob], name[0].newName + '.jpeg', { type: 'image/jpg' }));
});
}

So, On removing item from top to bottom the text box does not retain its value.因此,在从上到下删除项目时,文本框不会保留其值。 First was assigned for 091646 . First分配给091646

However, the finalFiles has the correct naming files.但是, finalFiles具有正确的命名文件。 Its just the textbox which has a problem.它只是有问题的文本框。

Please help me to retain the textbox values.请帮我保留文本框的值。 Thanks in advance.提前致谢。

Missing key s缺少key

The items in the v-for are not explicitly keyed in your markup, so Vue automatically keys them by their index. v-for中的项目没有在你的标记中显式地键入,因此 Vue 会自动通过它们的索引来键入它们。 As a rendering optimization, Vue reuses existing elements identified by their keys.作为渲染优化,Vue 重用了由其键标识的现有元素。 This can cause an issue when an item is added to or removed from the middle of the list, where surrounding items take on new keys equal to their new indices.当一个项目被添加到列表中间或从中删除时,这可能会导致问题,其中周围的项目采用与其新索引相等的新键。

Solution解决方案

Apply the key attribute to each v-for item using a unique ID (not equal to index ).使用唯一 ID (不等于index )将key属性应用于每个v-for项目。 In this case, the index combined with the filename would suffice:在这种情况下,结合文件名的index就足够了:

<div v-for="(item, index) in selectedFiles" :key="index + item.name">

Missing v-model s缺少v-model

When the template is re-rendered (occurs when removing an item from the middle of the list), the textboxes lose their values.重新渲染模板时(从列表中间删除项目时发生),文本框会丢失它们的值。 This is because they have no model bound to them.这是因为它们没有绑定到它们的模型。

Solution解决方案

Update renameFiles[] to store only strings (instead of objects), where each string corresponds to a file in selectedFiles[] by the same index .更新renameFiles[]以仅存储字符串(而不是对象),其中每个字符串对应于selectedFiles[]相同索引的文件。 That would obviate the file lookup code throughout your methods, so the code would be simplified to this:这将消除整个方法中的文件查找代码,因此代码将简化为:

export default {
  ⋮
  methods: {
    addFile(event) {
      this.selectedFiles = Array.from(event.target.files)
    },
    removeFile(e, item, index) {
      this.selectedFiles.splice(index, 1)
      this.renameFiles.splice(index, 1)
    },
    ⋮
  },
}

That change also enables using renameFiles[] as v-model on the <input> s for the rename strings:该更改还允许在重命名字符串的<input>上使用renameFiles[]作为v-model

<input type="text" v-model="renameFiles[index]" placeholder="Rename File" />

demo 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM