zoukankan      html  css  js  c++  java
  • 2/16 Vue 上传图片并预览的实现 ( 一 )

    写在前面

      现在还没有上传功能 只差个axios

      明天继续写

      今天先放个代码

      这个东西可以直接复制用

      但是上传的文件位置和渲染出来的不一样,估计是底层的东西问题,我没有解决方案 ( for 循环的机制 )


      2/17 补充 现在写完了

      https://www.cnblogs.com/WaterMealone/p/14409454.html


       

      1 <!DOCTYPE html>
      2 <html lang="zh-CN">
      3 
      4 <head>
      5     <meta charset="UTF-8">
      6     <title>Document</title>
      7     <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
      8     <!-- 引用一个css库 -->
      9     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
     10 </head>
     11 
     12 <body>
     13     <div id="app">
     14         <div class="container">
     15 
     16             <div class="title-container">
     17                 <span>上传文件</span>
     18             </div>
     19 
     20             <div class="upload-box">
     21                 <div class="drag-box" ref="dragBox" :class="isDrag? 'draging-drag-box':'' ">
     22                     <label>
     23                         <div class="icon-container">
     24                             <i class="fa fa-file" :class="isDrag? 'draging-fa-file': ''"></i>
     25                         </div>
     26                         <div class="label-text-container">
     27                             <span :class="isDrag? 'draging-label-text-container':'' ">请将文件拖动至此</span>
     28                             <br>
     29                             <span :class="isDrag? 'draging-label-text-container':'' ">或者单击上传</span>
     30                         </div>
     31                         <input type="file" accept="image/jepg, image/png" name="pictures"
     32                             @change="storepreFiles($event.target)" multiple>
     33                     </label>
     34                 </div>
     35 
     36                 <div class="show-file-box" v-if=" files.length == 0 ? false : true">
     37 
     38                     <div class="text-container">
     39                         <span>上传列表</span>
     40                         <span>{{updateState}} / {{preFilesLength}}</span>
     41                     </div>
     42                     <!-- 渲染出来的情况 有一个进度条 -->
     43                     <div class="pre-upload-bar">
     44                         <div>
     45                             <span>列表加载进度 {{(updateState / preFilesLength).toFixed(1) *100}} %</span>
     46                         </div>
     47                         <div class="pre-upload-bar-done"
     48                             :style="{  ( updateState / preFilesLength ) *100 + '%' }">
     49                         </div>
     50                     </div>
     51                     <!-- <div v-if="updateState === preFilesLength ? true : false"> -->
     52 
     53                     <ul class="pre-upload-list">
     54                         <transition-group tag="li" name="list">
     55                             <li class="pre-upload-file" v-for="file in preFiles" :key="file.name">
     56                                 <div class="review">
     57                                     <!-- 图片预览 -->
     58                                     <div class="review-image-container">
     59                                         <img class="review-image" :src="file.src">
     60                                     </div>
     61 
     62                                     <div class="review-file-name-container">
     63                                         <span class="file-name"> {{ file.name }}</span>
     64                                     </div>
     65                                     <div class="progress">
     66                                         <div class="progress-done" :style="{  file.index + '%' }"></div>
     67                                     </div>
     68                                     <span class="percent">{{ file.index }}%</span>
     69                                     <input class="select-box" check type="checkbox" name="select" :value="file.name"
     70                                         :checked="file.isChecked" @change="doSelect(file.name)" ref="select" />
     71                                 </div>
     72                             </li>
     73                         </transition-group>
     74                     </ul>
     75 
     76 
     77                     <hr color="lightpink" style="margin: 10px 8px;">
     78                     <!-- 选择按钮 -->
     79                     <div class="bottom-select">
     80                         <span class="bottom-select-button" @click="seletAll">{{ select }}</span>
     81                         <div class="bottom-select-info">
     82                             <div> <span>已选</span> <span class="span-special"
     83                                     :style="{'color':  showSize() > 15 ? 'red':'green'}">{{showSelect()}} </span>
     84                                 <span>/{{preFilesLength}}</span>
     85                             </div>
     86                             <div> <span class="span-special" :style="{'color':  showSize() > 15 ? 'red':'green'}">{{
     87                                     showSize() }} </span> <span>/ {{showAllSize()}} mb </span></div>
     88                         </div>
     89                     </div>
     90 
     91                     <div class="bottom-upload">
     92                         <span>上传</span>
     93                     </div>
     94 
     95 
     96                 </div>
     97             </div>
     98 
     99         </div>
    100 
    101     </div>
    102 </body>
    103 
    104 <script>
    105     var vm = new Vue({
    106         el: '#app',
    107         data() {
    108             return {
    109                 // 预展示的图片对象数组
    110                 preFiles: [],
    111                 // preFiles: (function (num) {
    112                 //     var temp = new Array
    113                 //     for (let i = 0; i < num; i++) {
    114                 //         temp.push(0)
    115                 //     }
    116                 //     return temp
    117                 // })(9),
    118 
    119                 preFilesLength: 0,
    120                 // 这个是渲染list的过程 渲染到第几个li
    121                 updateState: 0,
    122 
    123                 // 真正要上传的图片文件
    124                 files: [],
    125 
    126                 // 选择上传的文件
    127                 select: "全选",
    128 
    129                 // 是否进行拖动事件
    130                 isDrag: false
    131             }
    132         },
    133         updated() {
    134         },
    135         mounted: function () {
    136             var dragBox = this.$refs.dragBox;
    137             dragBox.addEventListener('dragenter', this.onDrag, false);
    138             dragBox.addEventListener('dragover', this.onDrag, false);
    139             dragBox.addEventListener('dragleave', () => { this.isDrag = false; }, false);
    140             dragBox.addEventListener('drop', this.onDrop, false);
    141         },
    142         watch: {
    143             // 通过对 preFiles 监听 实现简单加载文件进度条
    144             preFiles: {
    145                 handler: 'updateS'
    146             }
    147         },
    148         methods: {
    149             storepreFiles(obj) {
    150                 // 获取input里面的文件组
    151                 var fileList = obj.files;
    152                 // 先判定有没有重复提交的文件 可以加判断条件
    153                 for (let i = 0; i < fileList.length; i++) {
    154                     for (let j = 0; j < this.preFiles.length; j++) {
    155                         if (this.preFiles[j].name === fileList[i].name) {
    156                             alert("有文件重复")
    157                             return
    158                         }
    159                     }
    160                 }
    161 
    162                 this.preFilesLength = this.preFilesLength + fileList.length
    163 
    164                 // 这样防止变成 两个Filelist 对象 组合
    165                 for (var i = 0; i < fileList.length; i++) {
    166                     this.files = this.files.concat(fileList[i])
    167                 }
    168                 var vue = this
    169                 //对文件组进行遍历,可以到控制台打印出fileList去看看
    170                 for (let i = 0; i < fileList.length; i++) {
    171 
    172                     function uploadFile(file) {
    173                         return new Promise(function (resolve, reject) {
    174                             let reader = new FileReader()
    175                             reader.readAsDataURL(file)
    176                             reader.onload = function () {
    177                                 resolve(this.result)
    178                             }
    179                         })
    180                     }
    181                     uploadFile(fileList[i]).then(function (result) {
    182                         console.group(i)
    183                         console.log(event)
    184                         console.log(fileList[i])
    185                         console.groupEnd()
    186                         // vue.preFiles.splice(i, 0, { name: fileList[i].name, size: fileList[i].size, index: 0, })
    187                         vue.preFiles.push({ name: fileList[i].name, size: fileList[i].size, index: 0, src: result, isChecked: true })
    188                     })
    189                 }
    190             },
    191 
    192             // 渲染列表的参数
    193             updateS() {
    194                 this.updateState = this.updateState + 1
    195             },
    196 
    197             findPreFile(name) {
    198                 let that = this
    199                 return this.preFiles.find((item, index) => {
    200                     return item.name === name;
    201                 })
    202 
    203             },
    204 
    205             // 点击 选择框 和 全选
    206             doSelect(name) {
    207                 this.preFiles.forEach(element => {
    208                     if (element.name == name) {
    209                         element.isChecked = !element.isChecked
    210                     }
    211 
    212                 });
    213 
    214             },
    215             seletAll() {
    216                 if (this.$refs.select.find(item => item.checked == false)) {
    217                     console.log(this.$refs.select)
    218                     this.preFiles.forEach(element => {
    219                         element.isChecked = true
    220                     })
    221                 }
    222 
    223             },
    224 
    225             // 显示 选中个数 和 显示 选中的文件大小
    226             showSelect() {
    227                 let num = 0
    228                 this.preFiles.forEach(element => {
    229                     if (element.isChecked == true) {
    230                         num++;
    231                     }
    232                 });
    233                 return num
    234             },
    235 
    236             showSize() {
    237                 let size = 0
    238                 this.preFiles.forEach(element => {
    239                     if (element.isChecked == true) {
    240                         size = size + element.size
    241                     }
    242                 });
    243                 return (size / Math.pow(2, 20)).toFixed(2)
    244             },
    245 
    246             showAllSize() {
    247                 let size = 0
    248                 this.preFiles.forEach(element => {
    249 
    250                     size = size + element.size
    251                 });
    252                 return (size / Math.pow(2, 20)).toFixed(2)
    253 
    254             },
    255 
    256             // 拖动文件上传
    257             onDrag: function (e) {
    258                 this.isDrag = true;
    259                 e.stopPropagation();
    260                 e.preventDefault();
    261                 //    var dragBox =  this.$refs.dragBox;
    262                 //    var faFile = this.$refs.faFile;
    263                 //    var textContainer = this.$refs.textContainer;
    264 
    265                 //    dragBox.onmouseover();
    266                 //    console.log(dragBox)
    267 
    268             },
    269 
    270             onDragLeave(e) {
    271 
    272             },
    273 
    274             onDrop: function (e) {
    275                 this.isDrag = false;
    276                 e.stopPropagation();
    277                 e.preventDefault();
    278                 var dt = e.dataTransfer;
    279                 this.storepreFiles(dt);
    280             }
    281         }
    282     });
    283 
    284 </script>
    285 
    286 <style>
    287     span {
    288         font-weight: 700;
    289         font: bolder;
    290     }
    291 
    292     .container {
    293         width: 450px;
    294         /* background-color: rgb(195, 209, 228); */
    295         box-shadow: 2px 2px 2px 2px rgba(68, 68, 68, 0.2);
    296         border-radius: 10px;
    297         padding: 20px;
    298     }
    299 
    300     .upload-box {
    301         /*  400px; */
    302         /* height: 400px; */
    303 
    304     }
    305 
    306     .title-container {
    307         margin: 10px 8px 20px 8px;
    308         font-size: 20px;
    309 
    310         border-radius: 5px;
    311         background: linear-gradient(to right, rgb(112, 158, 242), rgb(255, 255, 255));
    312         color: white;
    313     }
    314 
    315     .drag-box {
    316         padding: 20px;
    317         margin: 10px auto;
    318         width: 380px;
    319         border-radius: 10px;
    320         border: 5px dashed rgba(112, 155, 248, 0.7);
    321         text-align: center;
    322         transition: all linear 0.1s;
    323     }
    324 
    325     .label-text-container {
    326         margin: 20px 8px;
    327         font-size: 20px;
    328     }
    329 
    330     .text-container {
    331         margin: 20px 8px;
    332         font-size: 20px;
    333         border-radius: 5px;
    334         background: linear-gradient(to right, rgb(112, 158, 242), rgb(255, 255, 255));
    335         color: white;
    336     }
    337 
    338     .drag-box .label-text-container {
    339         color: rgba(190, 190, 190, 0.8);
    340         transition: all linear 0.1s;
    341     }
    342 
    343     .icon-container {
    344         margin: 15px;
    345     }
    346 
    347     .fa-file {
    348         color: rgba(247, 187, 219, 0.8);
    349         font-size: 100px;
    350         transition: all linear 0.1s;
    351     }
    352 
    353     /*  当进入文件的时候添加css */
    354     .drag-box:hover {
    355         border: 5px dashed rgba(112, 155, 248, 1);
    356     }
    357 
    358     .drag-box:hover .fa-file {
    359         color: rgb(245, 124, 188);
    360     }
    361 
    362     .drag-box:hover .label-text-container {
    363         color: rgb(68, 68, 68);
    364     }
    365 
    366 
    367 
    368     /*  当拖动文件的时候添加css */
    369     .draging-drag-box {
    370         border: 5px dashed rgba(112, 155, 248, 1);
    371     }
    372 
    373     .draging-fa-file {
    374         color: rgb(245, 124, 188);
    375     }
    376 
    377     .draging-label-text-container {
    378         color: rgb(68, 68, 68);
    379     }
    380 
    381     /*  点击上传文件的时候的那个input */
    382     label input {
    383         display: none;
    384     }
    385 
    386 
    387     .review {
    388         border: 1px solid transparent;
    389         border-radius: 5px;
    390         color: #777;
    391         display: flex;
    392         font-size: 12px;
    393         align-items: center;
    394         padding: 10px;
    395         margin: 5px 8px;
    396     }
    397 
    398     .review:hover {
    399         cursor: pointer;
    400         /* border: 1px solid #ddd; */
    401         box-shadow: 0 3px 10px -5px rgba(0, 0, 0, 0.7);
    402     }
    403 
    404     .pre-upload-bar {
    405         margin: 10px 10px;
    406         height: 20px;
    407     }
    408 
    409     .pre-upload-bar span {
    410         font-size: 12px;
    411         font-weight: 20px;
    412         color: #777
    413     }
    414 
    415     .pre-upload-bar-done {
    416         background: linear-gradient(to left, rgb(112, 158, 242), rgb(119, 140, 255));
    417         box-shadow: 0 3px 3px -5px rgb(100, 115, 143), rgb(134, 138, 165);
    418         border-radius: 5px;
    419         height: 3px;
    420         width: 0;
    421         transition: width ease 0.2s;
    422     }
    423 
    424     .review-file-name-container {
    425         width: 100px;
    426     }
    427 
    428     .review-image-container {
    429         margin: 0 8px 0 0;
    430     }
    431 
    432     .review-image {
    433         width: 50px;
    434     }
    435 
    436     .pre-upload-list {
    437         list-style: none;
    438         /*  取消缩进 */
    439         margin: 0px;
    440         padding: 0px
    441     }
    442 
    443     .file-name {
    444         width: 100%;
    445         float: left;
    446         overflow: hidden;
    447         text-overflow: ellipsis;
    448         white-space: normal;
    449     }
    450 
    451     .progress {
    452         background-color: rgba(100, 100, 100, 0.2);
    453         border-radius: 5px;
    454         position: relative;
    455         margin: 0 10px;
    456         height: 10px;
    457         width: 150px;
    458     }
    459 
    460     .progress-done {
    461         background: linear-gradient(to left, rgb(242, 112, 156), rgb(255, 148, 114));
    462         box-shadow: 0 3px 3px -5px rgb(242, 112, 156), 0 2px 5px rgb(242, 112, 156);
    463         border-radius: 5px;
    464         height: 10px;
    465         width: 0;
    466         transition: width ease 0.1s;
    467     }
    468 
    469     .select-box {
    470         width: 20px;
    471         height: 20px;
    472         margin: 0 0 0 36px;
    473     }
    474 
    475 
    476     /* list的transition group */
    477     .list-enter,
    478     .list-leave-to {
    479         opacity: 0;
    480     }
    481 
    482     .list-enter-active {
    483         animation: moveIn 1s;
    484     }
    485 
    486     .list-leave-active {
    487         animation: moveOut 1s;
    488         /* transition: all 1s linear; */
    489     }
    490 
    491     @keyframes moveIn {
    492         0% {
    493             opacity: 0;
    494             transform: translate(30px, 15px);
    495         }
    496 
    497         30% {
    498             opacity: 0.5;
    499             transform: translate(0px, 15px);
    500         }
    501 
    502         100% {
    503             opacity: 1;
    504             transform: translate(0, 0px);
    505         }
    506     }
    507 
    508     @keyframes moveOut {
    509         0% {
    510             opacity: 1;
    511             transform: translate(0, 0px);
    512         }
    513 
    514         30% {
    515             opacity: 0.5;
    516             transform: translate(0px, 15px);
    517         }
    518 
    519         100% {
    520             opacity: 0;
    521             transform: translate(30px, 15px);
    522         }
    523     }
    524 
    525 
    526     .bottom-select {
    527         margin: 5px 8px;
    528         padding: 0 10px;
    529         height: 40px;
    530     }
    531 
    532     .bottom-select .bottom-select-button {
    533         cursor: pointer;
    534         color: white;
    535         margin: 5px;
    536         padding: 7px;
    537         float: right;
    538         transition: all linear 0.1s;
    539         background-color: rgb(247, 159, 172);
    540         border-radius: 5px;
    541     }
    542 
    543     .bottom-select-info span {
    544         font-size: 15px;
    545         font-weight: 200;
    546     }
    547 
    548     .bottom-select-info .span-special {
    549         font-weight: 1000;
    550     }
    551 
    552     .bottom-upload {
    553         margin: 50px auto 10px auto;
    554         width: 80px;
    555         height: 40px;
    556         text-align: center;
    557         padding: 5px;
    558         border-radius: 5px;
    559         background-color: lightpink;
    560         color: white;
    561     }
    562     .bottom-upload span{
    563         letter-spacing:5px;
    564         margin: auto;
    565         font-size: 30px;
    566     }
    567 </style>
    568 
    569 </html>

    总结

      明天继续写

      写完把详细过程记录一下

    Let it roll
  • 相关阅读:
    娓娓道来c指针 (4)解析c的声明语句
    Snail—UI学习之UITextField
    E
    Qt录音机
    著名的英文搜索引擎
    java中Map,List与Set的差别
    Android图片处理:识别图像方向并显示
    Unity3D中组件事件函数的运行顺序
    Android屏幕density, dip等相关概念总结
    Codeforces Round #257 (Div. 2)
  • 原文地址:https://www.cnblogs.com/WaterMealone/p/14407875.html
Copyright © 2011-2022 走看看