• vue-upload 封装组件-上传组件


    我后端的,刚接触vue个星期,根据需求写了个上传控件,很灵活的。没有看element el-upload源码,样式用的element的。感觉vue确实好用。

    先看样子:

    <!-- 单文件上传组件 -->
    <template>
    <div>
      <input type="file" id="file" hidden @change="fileChange" :accept="accept">
      <div v-if="upMode=='url'" style=" 100%;display:inline-flex;">    
        <el-input :value="path" disabled></el-input>
        <el-button size="small" type="primary" @click="btnChange">{{autoUpload?label:'选择文件'}}</el-button>
        <el-button v-if="!autoUpload && loadButton" size="small" type="success" @click="uploadClick">{{label}}</el-button>    
      </div>
      <div v-else-if="upMode=='head'" class="upmode-head">
        <div class="el-upload el-upload--picture-card" @click="btnChange">
          <i v-if="path==''" class="el-icon-plus"></i>
          <img v-else :src="path">
        </div>
        <el-button v-if="!autoUpload && loadButton" size="small" type="success" @click="uploadClick">{{label}}</el-button>
      </div>
      <div v-else-if="upMode=='variable'" class="el-upload-dragger" @click="btnChange">
        <div v-if="path==''">
          <i class="el-icon-upload"></i><div class="el-upload__text"><em>{{label}}</em></div>
        </div>
        <img v-else :src="path">
      </div>   
    
    </div>    
    </template>
    
    <script>
      import glob from '@/utils/global.js'
      export default {
        model: {   
          prop: 'path',
          event: 'onsuccess'
        },
        props: {
          label: {type: String, default: '上传'},//按钮文字
          accept: {String,default:'image/jpeg,image/png,image/x-icon'},//预选文件类型
          autoUpload:{type:Boolean, default:true},//是否自动上传
          loadButton:{type:Boolean, default:true},//手动上传时是否生成上传按钮
          path:String,//回显地址
          action: {type: String, default: '/api/upload/img'},//传入action可以调用不同接口适应不同文件类型上传
          upMode:{type: String, default: 'url'},//上传控件模式url,head,variable
        },
        methods: {
          btnChange() {
            var file = document.getElementById('file');
            file.click();
          },
          fileChange(e){
            try {          
              const fu = this.getFile();   
              if(fu==null)return;   
              if(!this.beforeUpload(fu))return;
              if(this.autoUpload){
                this.submit(fu);
              }else{
                if(this.upMode=='url')return; 
                //本地预览
                var reader = new FileReader();
                reader.readAsDataURL(fu);                    
                reader.onload = function(e) {
                  var src = this.result;
                  var str = '<img src="'+src+'">';
                  var target=this.upMode=='head'?'.el-upload--picture-card':'.el-upload-dragger';
                  var nim = document.querySelector(target);
                  if(nim) {
                    nim.innerHTML='';
                    nim.insertAdjacentHTML("beforeEnd", str)
                  }
                };
              }
                
            } catch (error) {
              console.debug('choice file err:',error);
            }
          },
          beforeUpload(f) {
            const maxSzie = glob.Config.UploadSize;
            if (f.size/1024/1024 > maxSzie) {
              this.$message.error('上传文件大小不能超过'+maxSzie+'M.');
              return false;
            }
            var types = glob.Config.UploadType;
            for (let i = 0; i < types.length; i++) {
              if(types[i]===f.type) return true;          
            }
            this.$message.error('上传文件格式不允许!');
            return false;
          },
          uploadClick(e){
            this.submit();
          },
          submit(file){
          try {
            if(!file) file = this.getFile();
            if(file==null)return;
            var isUpload =true;
            this.$emit('onbefore', file);
            if(!isUpload)return;
            const url =process.env.Store_API + this.action;
            var fd = new window.FormData();
            // 配置post请求的参数。参数名fileType,值为category(看后端的具体要求)
            fd.append('fileType', 'category');
            fd.append('file', file);
            var xhr = new XMLHttpRequest();
            xhr.open('POST', url, true);
            xhr.send(fd);
            xhr.onload = () => {
              if (xhr.status === 200) {
                var res = JSON.parse(xhr.responseText);
                if(res.code==1) {
                  var imgurl = glob.StaticStoreHost+res.data;
                  this.$emit('onsuccess', imgurl);
                }else{ 
                  this.$message(res.message);
                }
              }
            }
          } catch (error) {
            console.debug('upload file err:',error);
          }   
          },
          getFile(){
            var file = document.getElementById('file');
            if(file.files.length==0){
              this.$message('没有选择文件');
              return null;
            }
            return file.files[0];
          },
        },    
        
      }
    </script>

    其实就这个小组件就体现到封装、继承、多态的思想,多花时间思考,代码就能简洁、灵活、可用性高。

    样式也有重写,需要样式的评论支持下,谢谢。

  • 相关阅读:
    Centos 卸载 MySQL
    Kafka体系架构、命令、Go案例
    Go 平滑重启(优雅重启)
    etcd集群数据迁移至新集群
    ubuntu 20.04使用TLSv1
    mybatis拦截器对SQL处理,数据权限逻辑控制
    java敏感字查找和替换
    SpringBoot自定义validation验证
    java使用druid解析器解析SQL语句
    国产数据库人大金仓 KingbaseES V8 R2 在 x86_64 Linux 安装过程
  • 原文地址:https://www.cnblogs.com/he-bo/p/11134912.html
Copyright © 2020-2023  润新知