zoukankan      html  css  js  c++  java
  • vue的formdata图片预览以及上传

      1 <template>
      2   <div class="vue-uploader">
      3     <div class="file-list">
      4       <section v-for="(file, index) of files" class="file-item draggable-item">
      5         <img :src="file.src" alt="" ondragstart="return false;">
      6         <p class="file-name">{{file.name}}</p>
      7         <span class="file-remove" @click="remove(index)">+</span>
      8       </section>
      9       <section v-if="status === 'ready'" class="file-item">
     10         <div @click="add" class="add">
     11           <span>+</span>
     12         </div>
     13       </section>
     14     </div>
     15 
     16     <section v-if="files.length !== 0" class="upload-func">
     17       <div class="progress-bar">
     18         <section v-if="uploading" :width="(percent * 100) + '%'">{{(percent * 100) + '%'}}</section>
     19       </div>
     20       <div class="operation-box">
     21         <button v-if="status === 'ready'" @click="submit">上传</button>
     22         <button v-if="status === 'finished'" @click="finished">完成</button>
     23       </div>
     24     </section>
     25     <input type="file" accept="image/*" @change="fileChanged" ref="file" multiple="multiple">
     26 
     27     <el-upload
     28       action="https://jsonplaceholder.typicode.com/posts/"
     29       list-type="picture-card"
     30       :auto-upload="false"
     31       :limit="9"
     32       :on-preview="handlePictureCardPreview"
     33       :on-remove="handleRemove"
     34       :http-request="uploadFile"
     35       ref="upload"
     36       accept="image/png,image/gif,image/jpg,image/jpeg"
     37     >
     38       <i class="el-icon-plus"></i>
     39     </el-upload>
     40     <el-dialog :visible.sync="dialogVisible">
     41       <img width="100%" :src="dialogImageUrl" alt="">
     42     </el-dialog>
     43     <el-button type="primary" @click="subPicForm">上传</el-button>
     44   </div>
     45 </template>
     46 
     47 <script>
     48   import axios from "axios"
     49 
     50   export default {
     51     // props: {
     52     //   src: {
     53     //     type: String,
     54     //     required: true
     55     //   }
     56     // },
     57     data() {
     58       return {
     59         status: 'ready',
     60         files: [],
     61         point: {},
     62         uploading: false,
     63         percent: 0,
     64         dialogImageUrl: '',
     65         dialogVisible: false,
     66         formDate: ""
     67       }
     68     },
     69     methods: {
     70       add() {
     71         this.$refs.file.click()
     72       },
     73       submit() {
     74         if (this.files.length === 0) {
     75           console.warn('no file!');
     76           return
     77         }
     78         const formData = new FormData();
     79         this.files.forEach((item) => {
     80           formData.append(item.name, item.file)
     81         });
     82         const xhr = new XMLHttpRequest();
     83         xhr.upload.addEventListener('progress', this.uploadProgress, false);
     84         xhr.open('POST', "/api/upload", this.src, true);
     85         this.uploading = true;
     86         xhr.send(formData);
     87         xhr.onload = () => {
     88           this.uploading = false;
     89           if (xhr.status === 200 || xhr.status === 304) {
     90             this.status = 'finished';
     91             console.log('upload success!')
     92           } else {
     93             console.log(`error:error code ${xhr.status}`)
     94           }
     95         }
     96       },
     97       finished() {
     98         this.files = [];
     99         this.status = 'ready'
    100       },
    101       remove(index) {
    102         this.files.splice(index, 1)
    103       },
    104       fileChanged() {
    105         const list = this.$refs.file.files;
    106         for (let i = 0; i < list.length; i++) {
    107           if (!this.isContain(list[i])) {
    108             const item = {
    109               name: list[i].name,
    110               size: list[i].size,
    111               file: list[i]
    112             };
    113             this.html5Reader(list[i], item);
    114             this.files.push(item)
    115           }
    116         }
    117         this.$refs.file.value = ''
    118       },
    119       // 将图片文件转成BASE64格式
    120       html5Reader(file, item) {
    121         const reader = new FileReader();
    122         reader.onload = (e) => {
    123           this.$set(item, 'src', e.target.result)
    124         };
    125         reader.readAsDataURL(file)
    126       },
    127       isContain(file) {
    128         this.files.forEach((item) => {
    129           if (item.name === file.name && item.size === file.size) {
    130             return true
    131           }
    132         });
    133         return false
    134       },
    135       // 上传进度
    136       uploadProgress(evt) {
    137         const component = this;
    138         if (evt.lengthComputable) {
    139           const percentComplete = Math.round((evt.loaded * 100) / evt.total);
    140           component.percent = percentComplete / 100
    141         } else {
    142           console.warn('upload progress unable to compute')
    143         }
    144       },
    145       // elementUI上传
    146       uploadFile(file) {
    147         this.formDate.append('file', file.file);
    148       },
    149       handlePictureCardPreview(file) {
    150         this.dialogImageUrl = file.url;
    151         this.dialogVisible = true;
    152       },
    153       handleRemove(file, fileList) {
    154         console.log(file, fileList);
    155       },
    156       subPicForm() {
    157         this.formDate = new FormData();
    158         this.$refs.upload.submit();
    159         this.formDate.append('WS_CODE', "12133");
    160         let config = {
    161           headers: {
    162             'Content-Type': 'multipart/form-data'
    163           }
    164         };
    165         axios.post("/api/upload", this.formDate, config).then(res => {
    166           console.log(res)
    167         }).catch(res => {
    168           console.log(res)
    169         })
    170       }
    171     }
    172   }
    173 </script>
    174 
    175 <style scoped>
    176   .vue-uploader {
    177     border: 1px solid #e5e5e5;
    178   }
    179 
    180   .vue-uploader .file-list {
    181     padding: 10px 0px;
    182   }
    183 
    184   .vue-uploader .file-list:after {
    185     content: '';
    186     display: block;
    187     clear: both;
    188     visibility: hidden;
    189     line-height: 0;
    190     height: 0;
    191     font-size: 0;
    192   }
    193 
    194   .vue-uploader .file-list .file-item {
    195     float: left;
    196     position: relative;
    197      100px;
    198     text-align: center;
    199   }
    200 
    201   .vue-uploader .file-list .file-item img {
    202      80px;
    203     height: 80px;
    204     border: 1px solid #ececec;
    205   }
    206 
    207   .vue-uploader .file-list .file-item .file-remove {
    208     position: absolute;
    209     right: 12px;
    210     display: none;
    211     top: 4px;
    212      14px;
    213     height: 14px;
    214     color: white;
    215     cursor: pointer;
    216     line-height: 12px;
    217     border-radius: 100%;
    218     transform: rotate(45deg);
    219     background: rgba(0, 0, 0, 0.5);
    220   }
    221 
    222   .vue-uploader .file-list .file-item:hover .file-remove {
    223     display: inline;
    224   }
    225 
    226   .vue-uploader .file-list .file-item .file-name {
    227     margin: 0;
    228     height: 40px;
    229     word-break: break-all;
    230     font-size: 14px;
    231     overflow: hidden;
    232     text-overflow: ellipsis;
    233     display: -webkit-box;
    234     -webkit-line-clamp: 2;
    235     -webkit-box-orient: vertical;
    236   }
    237 
    238   .vue-uploader .add {
    239      80px;
    240     height: 80px;
    241     margin-left: 10px;
    242     float: left;
    243     text-align: center;
    244     line-height: 80px;
    245     border: 1px dashed #ececec;
    246     font-size: 30px;
    247     cursor: pointer;
    248   }
    249 
    250   .vue-uploader .upload-func {
    251     display: flex;
    252     padding: 10px;
    253     margin: 0px;
    254     background: #f8f8f8;
    255     border-top: 1px solid #ececec;
    256   }
    257 
    258   .vue-uploader .upload-func .progress-bar {
    259     flex-grow: 1;
    260   }
    261 
    262   .vue-uploader .upload-func .progress-bar section {
    263     margin-top: 5px;
    264     background: #00b4aa;
    265     border-radius: 3px;
    266     text-align: center;
    267     color: #fff;
    268     font-size: 12px;
    269     transition: all .5s ease;
    270   }
    271 
    272   .vue-uploader .upload-func .operation-box {
    273     flex-grow: 0;
    274     padding-left: 10px;
    275   }
    276 
    277   .vue-uploader .upload-func .operation-box button {
    278     padding: 4px 12px;
    279     color: #fff;
    280     background: #007ACC;
    281     border: none;
    282     border-radius: 2px;
    283     cursor: pointer;
    284   }
    285 
    286   .vue-uploader > input[type="file"] {
    287     display: none;
    288   }
    289 </style>
  • 相关阅读:
    使用字体图标完整步骤
    用position:absolute定位小窗口位于版面正中心
    MySql 技术内幕 (第7章 游标)
    MySql 技术内幕 (第5章 联接与集合操作)
    赋值语句作为判断的条件
    发布订阅模式和观察者模式
    关系代数
    数据库关系代数表达式学习
    软考通过分数
    哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度
  • 原文地址:https://www.cnblogs.com/ronle/p/10868196.html
Copyright © 2011-2022 走看看