美文网首页
vue+css让新增元素背景闪烁一次

vue+css让新增元素背景闪烁一次

作者: 一个废人 | 来源:发表于2018-02-04 15:51 被阅读15次

工作中要做一个上传文件面板,初始化时面板部分有已上传文件列表。
根据ant-design设计原则解释刚刚发生了什么
原则,我想让新上传的文件行闪烁一下。
于是就有了下面的代码,新增了.blink的css,增加到新增行里去。现在准备出去玩,所以直截了当贴代码,(相关代码ctrl+f搜索'blink'就可以了):

<template>
  <div class="documents-uploader-container">
    <div class="documents-uploader-header">
      {{loanDocument.name}}
    </div>
    <div class="documents-uploader-question-mark">
      <i class="fa fa-question-circle" aria-hidden="true" v-b-popover.hover="popoverConfig"></i>
      <span>{{loanDocument.description}}</span>
    </div>
    <div class="documents-uploader-area">
      <button class="btn btn-primary" v-if="loanDocument.multiple">
        Buscar
        <input type="file" value="Buscar" :accept="loanDocument.type" multiple="multiple" @change="uploadHandler($event)" class="upload-file-input">
      </button>
      <button class="btn btn-primary" disabled v-if="!loanDocument.multiple">
        Buscar
      </button>
      <!-- uploaded files -->
      <div class="documents-uploader-documents-list" v-for="file in fileList">
        <div class="uploaded-file-container" :class="{'blink':file.blink}" v-if="!file.uploading">
          <span>{{file.name}}</span>
          <div class="operation-btn">
            <i class="fa fa-download" aria-hidden="true" @click="download(file)"></i>
            <click-confirm style="font-size:24px" :messages="{title:'¿Seguro que quieres eliminarlo?',yes:'sí',no:'no'}">
              <i class="fa fa-times-circle" aria-hidden="true" style="margin-left:10px" @click="deleteExistedFile(file)"></i>
            </click-confirm>
          </div>
        </div>
        <div class="uploading-file-container" v-if="file.uploading">
          <div class="file-uploading-progress-bar" :style="{width:file.progress}"></div>
          <div class="file-uploading-detail-wrapper">
            <span>{{file.name}}</span>
            <div class="operation-btn">
              <click-confirm style="font-size:24px" :messages="{title:'¿Seguro que quieres eliminarlo?',yes:'sí',no:'no'}">
                <i class="fa fa-times-circle" aria-hidden="true" style="margin-left:10px" @click="deleteExistedFile(file)"></i>
              </click-confirm>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Vue from 'vue'
import { upload,download,remove } from '../utils/api.js'
let FormData = require('form-data');
import clickConfirm from 'click-confirm'
import 'vue-progress-path/dist/vue-progress-path.css'
import VueProgress from 'vue-progress-path'
Vue.use(VueProgress)

export default {
  name: 'DocumentsUploader',
  props: [ 'loanId','loanDocument','validationCallback','onError' ] ,
  components: { clickConfirm,VueProgress },
  data() {
    return {
      fileStack:[...this.loanDocument.files],
      filesWaitingForUpload : [],
    }
  },
  methods: {
    uploadHandler(e){
      let files = e.target.files
      for(let i=0;i<files.length;i++){
        let file = files[i]
        let obj = {}
        obj.name = file.name
        obj.uploading = true
        obj.progress = 0
        this.fileStack.push(obj)
        //formData to upload
        let formData = new FormData();
        formData.append('file', file);
        let data = {}
        data.loanId = this.loanId
        data.docId = this.loanDocument.id
        data.filename = file.name
        data.file = formData
        //callback to get upload progress
        let callback = (progress)=>{
          obj.progress = progress + "%"
        }
        upload(data,callback).then((response)=>{
          setTimeout(()=>{
            obj.uploading = false
            this.validate()
                  obj.blink = true
          },1500)
        }).catch((err)=>{
          this.onError()
        })
      }
    },
    deleteExistedFile(file){
      for(let i=0;i<this.fileStack.length;i++){
        let item = this.fileStack[i]
        if(item.name === file.name || item === file.name){//"item === file.name" compatible for the backend just pass a array of filenames to the frontend
          this.fileStack.splice(i,1)
        }
      }
      let data = {}
      data.loanId = this.loanId
      data.docId = this.loanDocument.id
      data.filename = file.name
      return remove(data).then((res)=>{

      }).catch((e)=>{

      })
    },
    download(file){
      let data = {}
      data.loanId = this.loanId
      data.docId = this.loanDocument.id
      data.filename = file.name
      return download(data).then((res)=>{

      }).catch((e)=>{

      })
    },
    validate(){
      let docId = this.loanDocument.id
      let checkUploaded = (file) => {
        return file.uploading === false
      }
      if(docId === 'name_transfer_voucher'){//if docId == 'name_transfer_voucher', it need 12 documents to be compeleted.
          this.fileList.filter(checkUploaded).length > 11 && this.validationCallback(docId)//tell parent compoent it is validated
      }else {
          this.fileList.filter(checkUploaded).length > 0 && this.validationCallback(docId)//tell parent compoent it is validated
      }
    }
  },
  computed: {
    popoverConfig () {
      return {
        html: true,
        content: () => { return this.loanDocument.text }
      }
    },
    fileList(){//filelist is a computed array displayed in frontend
      let arr = []
      this.fileStack.map((item)=>{
        let obj = {}
        if(typeof item !== 'object'){//compatible for the backend just pass a array of filenames to the frontend
          obj.name = item
          obj.uploading = false
        }else{
          obj = item
        }
        arr.push(obj)
      })
      return arr
    }
  },
  mounted(){
    this.validate()
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
@-webkit-keyframes blink {
    0% {
        background-color: #eff1f6;
        opacity:1;
    }
    50% {
        background-color: #fefade;
    }
    100% {
        background-color: #eff1f6;
    }
}

.blink {
    -webkit-animation-name: blink;
    -webkit-animation-duration: 2000ms;
    -webkit-animation-iteration-count: 1;
    -webkit-animation-timing-function: ease-in-out;
}
  >>> .vue-progress-path {
    width: 40px !important;
    height: 40px !important;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  >>> .vue-progress-path path {
    stroke-width: 10;
  }

  >>> .vue-progress-path .progress {
    stroke: #1f84be;
  }

  >>> .vue-progress-path .background {
    stroke: #ddd;
  }
  .btn.btn-primary{
    background: #1483c0;
    background: #1483c0;
    border:none;
    display:flex;
    justify-content:center;
    align-items:center;
    position:relative;
    width:100px;
  }
  .documents-uploader-container{
    padding: 0 15px;
  }
  .documents-uploader-header{
    font-size: 20px;
    padding: 15px 0 0;
    font-weight: 500;
  }
  .documents-uploader-question-mark{
    color:#fdc130;
    display: flex;
    align-items: center;
    font-size: 20px;
    padding: 15px 0;
  }
  .fa.fa-question-circle{
    font-size: 30px;
  }
  .documents-uploader-area{
    border: 1px solid #f2f2f2;
    padding: 10px;
  }
  .documents-uploader-documents-list > div{
    display: flex;
    margin-top: 5px;
    background: #eff1f6;
    align-items: center;
    color: #1483c0;
    justify-content: space-between;
  }
  .documents-uploader-documents-list span{
    /* flex:1; */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .operation-btn{
    display: flex;
    /* width: 80px; */
    padding-left: 10px;
    padding-right: 10px;
    align-items: center;
    /* justify-content: space-around; */
  }
  .operation-btn > i{
    font-size: 25px;
    transition: color 0.15s ease-in-out;
  }
  .operation-btn > i:active{
    color: #0e6fc9;
  }
  .upload-file-input{
    background:#f00;
    position:absolute;
    width:10px;
    opacity:0;
    left:0;
    top:0;
    height: 100%;
    width:100%;
  }
  /* uploading part */
  .uploaded-file-container{
    padding: 10px 15px;
  }
  .uploading-file-container{
    position:relative;
  }
  .file-uploading-progress-bar{
    transition:width 1s ease;
    position:absolute;
    height:100%;
    /* width:10%; */
    background:#1f84be;
    z-index:0
  }
  .file-uploading-detail-wrapper{
    color:#fff;
    padding: 10px 15px;
    display:flex;
    flex:1;
    justify-content:space-between;
    align-items:center;
    flex-direction:row;
    width:100%;
    z-index:1;
  }
  /* uploading part end*/
</style>

相关文章

网友评论

      本文标题:vue+css让新增元素背景闪烁一次

      本文链接:https://www.haomeiwen.com/subject/enbmzxtx.html