简体   繁体   English

在Vue.js中上传图片之前如何显示图片?

[英]How to show images before uploading them in Vue.js?

Following this tutorial, I've made this component which uploads multiple images at once, and shows the filenames to be uploaded. 遵循教程,我制作了此组件,该组件可一次上传多张图片,并显示要上传的文件名。

That works great, but I'm wondering how can I show the photos (ideally resized to certain max width) instead of their filenames? 效果很好,但我想知道如何显示照片(理想情况下将其调整为特定的最大宽度)而不是文件名?

      <div v-if="showUploadPhotoModal">
        <transition name="modal">
          <div class="modal-mask">
            <div class="modal-wrapper">

            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header"><strong>{{username}}</strong>&nbsp;&nbsp;
                        <h6 class="modal-title">Upload Photos <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-image"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21 15 16 10 5 21"></polyline></svg>
                        </h6>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true" @click="showUploadPhotoModal = false">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body">


                        <form @submit.prevent="sendFile" enctype="multipart/form-data">
                              <div class="form-group">
                                  <textarea class="form-control" rows="5" v-model="title" placeholder="Title"></textarea>

                              </div>

                              <div v-if="fileError" class="alert alert-danger">{{message}}</div>


                             <label class="upload-btn"><br>
                             <span>
                               <img class="logo img-responsive" src="../assets/images/upload.png">
                               <br>
                             </span>
                                Upload Files <input multiple type="file" @change="selectFile" ref="files" hidden>
                                 <br>

                             </label>
                            </form>   

                    </div>

                  <div class="field">
                    <div v-for="(file, index) in files"  :key="index" class="row photo-list" >

                      <div class="col-10 col-push-6">
                        <div :class="`text-right ${file.invalidMessage ?'red':'black'}`">{{file.name}} 

                          <span v-if="file.invalidMessage!=''">&nbsp; <small>{{file.invalidMessage}}</small> </span>
                        </div>

                      </div>
                      <div class="col-2">
                        <div class="text-left">
                          <a @click.prevent="files.splice(index, 1);uploadFiles.splice(index, 1)" class="remove-btn"> <strong >&times;</strong></a>
                        </div>
                      </div>
                    </div>

                  </div>

                    <span @click="sendFile" class="btn btn-primary">Send</span>

                </div>
            </div>

            </div>
          </div>
        </transition>
      </div>





 data () {
    return { 
        showUploadPhotoModal: false,
        files: [],
        uploadFiles: [],
        title: "",
        message: "",
        fileError: false,


    }
  },
  methods: {
    selectFile() {
      const files = this.$refs.files.files;
      this.uploadFiles = [...this.uploadFiles, ...files];
  this.files = [
       ...this.files,
       ..._.map(files, file => ({
         name: file.name,
         type: file.type,
         invalidMessage: this.validate(file)

       }))
  ];

},

validate(file) {
  const allowedTypes = ["image/jpeg", "image/png", "image/gif"];
  if(!allowedTypes.includes(file.type)) { 
    return "Not an image"
  }
  return "";
},

sendFile() {
  const formData = new FormData();

  formData.append('title', this.title);
  formData.append('token', this.token);

  _.forEach(this.uploadFiles, file => {
    if(this.validate(file)==="") {
      formData.append('files', file);
    }
  });

  axios.post(this.BASE_URL + "/api/post", formData)
  .then(res => {
    console.log('res data is:', res.data);
    this.files=[];
    this.uploadFiles=[];
    })
  .catch(err => {
    console.log('error is', err.response.data.error)
    this.fileError = true;
    });
}


  },

In order to handle this, I began with this layout: 为了解决这个问题,我从以下布局开始:

<div id="app" v-cloak>
  <input type="file" multiple accept="image/*"
     @change="handleSelects" name="images">
  <div v-for="image in images">
    <img :src="image" class="preview">
  </div>
</div>

I've got an input tag using @change to run a method whenever the user selects some files. 每当用户选择一些文件时,我都有一个使用@change的输入标签来运行方法。 Beneath it I've got a v-for to iterate and provide thumbnails for the images. 在它下面,我有一个v-for来迭代并提供图像的缩略图。

Here is the JavaScript: 这是JavaScript:

const app = new Vue({
  el:'#app',
  data:{
    images:[]
  },
  methods:{
    handleSelects(e) {
      this.images = [];
      let fileList = Array.prototype.slice.call(e.target.files);
      fileList.forEach(f => {

        if(!f.type.match("image.*")) {
          return;
        }

        let reader = new FileReader();
        let that = this;

        reader.onload = function (e) {
          that.images.push(e.target.result);
        }
        reader.readAsDataURL(f); 
      });
    }
  }
})

So handleSelects does a few things. 因此handleSelects会做一些事情。 First, it resets the thumbnails (this.images). 首先,它重置缩略图(this.images)。 It then looks at the files selected in the input, checks to see they are images, and sets up a FileReader for each. 然后,它查看在输入中选择的文件,检查它们是否是图像,并为每个文件设置一个FileReader。 For each file it gets a data url which is then added to that images array so previews can be created. 对于每个文件,它都有一个数据URL,然后将其添加到该图像数组,以便可以创建预览。

You can see a full CodePen of this here: https://codepen.io/cfjedimaster/pen/VqrGQw?editors=1111 您可以在此处查看完整的CodePen: https ://codepen.io/cfjedimaster/pen/VqrGQw?editors = 1111

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

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