上传多个文件,一个接一个,用BootstrapVue b-form-file [英] Upload multiple files, picking them one by one, with BootstrapVue b-form-file

查看:26
本文介绍了上传多个文件,一个接一个,用BootstrapVue b-form-file的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 BootstrapVue 中使用 b-form-file 上传文件,将 multiple 设置为 true 可以完美地处理多个文件,但是每次我选择一个文件时,它都会删除任何以前添加的文件.并且这些文件通常会分布在多个文件夹中,因此我需要能够从一个文件夹中选择一个文件,选择它,从另一个文件夹中选择另一个文件,等等.

这是 HTML:

我试过添加

ref="fileUpload";

到 b-form-file 标签,然后在 formatAssetUpload 函数中设置值,但这不起作用.那里有一个 setFiles 函数,但它似乎没有任何影响.我尝试在提交时捕获表单并手动将文件添加到 formdata 但这也不起作用,无论我尝试什么,总是只有最后一个/多个文件被选择通过后端.

有什么想法吗?

感谢您的帮助!:)

解决方案

如果你想记住用户选择的文件对象,你可以使用这个 javascript:

new Vue({el: '#app',数据() {返回 {文件:[],文件累积:[]}},方法: {onChange(事件){this.files.forEach(thisFile => {this.filesAccumulated.push(thisFile)})},onReset() {this.filesAccumulated = []}}})

连同这个 vue 模板

<b-表单文件v-model=文件"多重平原v-on:input="onChange"></b-form-file><div><ul><li v-for="thisFile in filesAccumulated">{{ thisFile.name }}

<b-button v-on:click="onReset">重启</b-按钮>

当用户执行选择时,b-form-file vue 组件会发出一个 input 事件.可以拾取文件对象来自与 v-model 指令绑定的变量.请参阅文档

看看这个小提琴 https://jsfiddle.net/1xsyb4dq/2/ 看看运行中的代码.

一般评论

让我对您的代码示例和一般的 b-form-file 组件发表一些评论:使用 bootstrap-vue 和 并不是使用封闭表单标签以提交表单.相反,您使用 vue 的 v-model 功能来获取 文件对象 来自 vue 的数据对象.

我在这里创建了一个更全面的例子 https://jsfiddle.net/to3q7ags/,但是我会一步一步解释:

v-model 属性的值是 vue 数据属性的名称:

在用户点击文件输入字段中的浏览",选择文件并按下确定后,vue 数据属性将保存一个文件对象数组:

new Vue({el: '#app',数据() {返回 {文件:[]//最初为空,但将在文件选择后填充}}})

来自 b-form 文件文档:

<块引用>

当没有选择任何文件时,将返回一个空数组.当一个选择一个或多个文件,返回值将是一个数组JavaScript File 对象实例.

用户选择文件后,您可以通过单击按钮或更改事件将文件发送到您的服务器.

提交</b-按钮>

对应的vue方法是这样的

方法:{提交(){//处理每个文件this.files.forEach(thisFile => {console.log("提交" + thisFile.name)//这里添加提交逻辑}}

要提交文件,您需要手动创建一个使用 multipart/form-data 编码的 http 发布请求.这可以通过使用 FormData 类来完成.

const formBody = new FormData()formBody.set("formParameter", thisFile)

FormData.set() 方法接受文件 blob 作为参数.然后你可以使用 XMLHttpRequest.send() 或 fetch() 来发送 post 请求:

获取(https://yourserver/post",{方法:'POST',正文:formBody}).then(response => console.log(response))

现在所有选定的文件都已发布到服务器.用户可以使用相同的表单重复该过程,选择新的文件集并再次按下发布按钮.

您还可以通过侦听 'input' 事件,在不使用按钮的情况下自动发送表单.拖放也有效.

I'm uploading files with b-form-file in BootstrapVue, setting multiple to true works perfectly for multiple files, BUT each time I choose a file it removes any previously added ones. And the files will often be spread across multiple folders, so I need to be able to pick a file from one folder, choose it, pick another file from another folder, and so on.

Here's the HTML:

<b-form ref="form" novalidate action="upload" method="post" enctype="multipart/form-data">
    <b-form-file name="file_upload[]" :multiple="true" :file-name-formatter="formatAssetUpload" no-drop placeholder="Click to choose"></b-form-file>
</b-form>

I've tried adding

ref="fileUpload" 

to the b-form-file tag and then in the formatAssetUpload function just setting the value, but that doesn't work. There's a setFiles function in there but it doesn't seem to affect anything. I tried catching the form on submit and manually adding the files to formdata but that's not working either, whatever I try there's always only the last file/files that were picked coming through on the backend.

Any ideas?

Thanks for any help! :)

解决方案

If you like to remember the file objects which have been selected by the user you an use this javascript:

new Vue({
  el: '#app',
  data() {
    return {
      files: [],
      filesAccumulated: []
    }
  },
  methods: {
    onChange(event) {
      this.files.forEach(thisFile => {
        this.filesAccumulated.push(thisFile)
      })       
    },
    onReset() {
        this.filesAccumulated = []
    }
  }
})

Together whit this vue template

<div id="app">
  <b-form-file
    v-model="files"
    multiple plain
    v-on:input="onChange">
  </b-form-file>
  <div>
    <ul>
      <li v-for="thisFile in filesAccumulated">
      {{ thisFile.name }}
      </li>
    </ul>
  </div>
  <b-button v-on:click="onReset">
    Reset
  </b-button>
</div>

The b-form-file vue component is emitting an input event when the user performs the selection. The file objects can be picked up from the variable bound with the v-model directive. See documentation

Look at this fiddle https://jsfiddle.net/1xsyb4dq/2/ to see the code in action.

General comments

Let me make some comments on your code example and b-form-file component in general: With bootstrap-vue and <b-form-file> it is not the idea to use an enclosing form tag to submit forms. Instead you use vue's v-model feature to obtain the file objects from vue's data object.

I have created a more comprehensive example here https://jsfiddle.net/to3q7ags/ , but I will explain step by step:

The value of the v-model attribute is the name of a vue data property:

<b-form-file v-model="files" multiple plain></b-form-file>

After the user has klicked 'Browse' in the file input field, has selected the files and pressed ok, the vue data property will hold an array of file objects:

new Vue({
  el: '#app',
  data() {
    return {
      files: [] 
      // initially empty, but will be populated after file selection
    }
  }
})

From the b-form file documentation:

When no files are selected, an empty array will be returned. When a file or files are selected the return value will be an array of JavaScript File object instances.

After files are selected by the user you can send the files to your server on a button click or change event.

<b-button v-on:click="onSubmit">
    Submit
</b-button>

the corresponding vue method looks like this

methods: {
  onSubmit() {
    // Process each file
    this.files.forEach(thisFile => {
      console.log("Submitting " + thisFile.name)
      // add submit logic here
    }
}

To submit the files you need to manually create a http post request which is using the multipart/form-data encoding. That can be done by using FormData class.

const formBody = new FormData()
formBody.set("formParameter", thisFile)

The FormData.set() method is accepting file blobs as arguments. Then you can use XMLHttpRequest.send() or fetch() to send the post request:

fetch(
  "https://yourserver/post",{
    method: 'POST',
    body: formBody})
    .then(response => console.log(response))

Now all selected files are posted to the server. The user can repeat the process with the same form, select new set of files and again press the post button.

You can also send the form automatically without the use of a button by listening to the 'input' event. Drag and drop also works.

这篇关于上传多个文件,一个接一个,用BootstrapVue b-form-file的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆