美文网首页
封装个vue上传图片小组件

封装个vue上传图片小组件

作者: peakol | 来源:发表于2018-05-29 20:10 被阅读0次

    今天在写设置界面的时候,遇见了更换图标这种类型的问题!感觉好熟悉,自己在写软件编辑的时候好像写个类似的功能,心里还有些后悔,直接引这里的不就好了嘛,自己写搞得多此一举。然而我试图检验一下功能的完整性。结果:


    这是什么鬼

    我擦,这是什么鬼?马上看了下代码逻辑,我去,顿时有想杀人的冲动----连个click都没有,静态页面!!好吧,不过幸好我之前写过类似的功能。立马高效很多,复用是一个程序员的基本素养。当然首先vue就秉承的是组件化系统,将每一个相同和和类似的功能抽象成组件,减少代码的重用和耦合,(PS:一写到这几句话,咋头脑中闪现了面向对象,封装,原型链。。。),竟然用vue,那就来实践框架的精髓。
    上传我们需要控制的是上传参数,当然请求都一样,没有后台约定的必要参数你的请求也请求不通。我们部门基本上上传约定的必须参数是文件的md5值,那么问题来了,之前提到MD5不都是后台给的吗?为啥后台先向我要!对,需要前端去计算MD5值,然后传给后端进行上传请求。所以组件里首先得有个计算md5的函数,我们再想想还需要些什么,上传文件总应该有些准备文件还有上传完成吧!所以向外面暴露两个API函数,一个是上传文件之前logoBe'foreUpload函数,这个函数主要是操作一些上传之前要干的事;另一个是上传完成之后logoUploadSucess函数,用来做一些logo的替换,或者加上logo的名字等等,所以我们这里要把处理完成的file对象emit出去。当然一些props,看你的需要,根据你的需要去书写,这里只是谈一些思路。
    好了!上面是对我业务的分析完成,开始封组件,这里ul我直接借用了element。我先把代码贴出来

    <template>
      <div>
        <el-upload :before-upload="logoBeforeUpload" :show-file-list="false" :on-success="logoUploadSucess"  :action="url"
          :data="postData">
          <el-button>浏览</el-button>
        </el-upload>
      </div>
    </template>
    <script>
      import SparkMD5 from 'spark-md5/spark-md5.min';
      export default {
        props: {
          url: {
            type: String
          },
          postData: {
            type: Object,
            default: function() {
              return {
                md5: ''
              }
            }
          }
        },
        data() {
          return {
    
          }
        },
        methods: {
          // 图片上传之前
          logoBeforeUpload(file) {
            const self = this
            // 当文件上传之前必须返回false或promise才能阻止文件上传,当我们对文件进行配置后,我们需要继续运行所以通过promise的resolve
            return new Promise((resolve, reject) => {
              self.fileMd5Calculate(file, (md5) => {
                console.log(md5);
                self.$set(self.postData, 'md5', md5)
                // self.postData.md5 = md5
                resolve()
              })
            })
          },
          // 图片上传成功之后
          logoUploadSucess(e, file) {
            // this.pngName = file.name
            // this.logoUrl = file.url
            this.$emit('success', file)
          },
          // 计算MD5值
          fileMd5Calculate(file, callBack) {
            console.log('file', file)
            let chunkSize = 1024 * 1024;
            this.fileReader = new FileReader();
            let chunks = Math.ceil(file.size / chunkSize),
              blobSlice =
              File.prototype.slice ||
              File.prototype.mozSlice ||
              File.prototype.webkitSlice,
              currentChunk = 0,
              spark = new SparkMD5.ArrayBuffer(),
              fileReader = new FileReader();
            console.log('spark', spark);
            console.log('fileReader', fileReader);
            console.log(11111);
            fileReader.onload = function(e) {
              spark.append(e.target.result);
              currentChunk++;
              if (currentChunk < chunks) {
                loadNext();
              } else {
                callBack(spark.end());
              }
            };
            fileReader.onerror = function() {
              console.warn('错误');
            };
    
            function loadNext() {
              let start = currentChunk * chunkSize,
                end = start + chunkSize >= file.size ? file.size : start + chunkSize;
              fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
            }
            console.log(22222);
            loadNext();
          }
        }
      }
    
    </script>
    
    <style scoped>
    </style>
    

    看代码可以看出我需要父组件传进来的是服务器地址,上传参数!当然这看每个人需要,需要啥传啥就行。
    首先计算文件MD5我用的是spark-md5.js,因为怕图片太大(也可能想多了,图片一般没有多大)我采取了分片计算md5的方法。计算md5完成后通过回调函数传出,在图片上传之前传出我们调用这个函数,然后配置上传参数。然后其实就到图片上传完成之后了,完成之后的操作肯定是通过父组件完成,我们把file对象传到父组件,给父组件绑定success方法

     <upload-img class="img-upload" url="/sfmgapi/upload/add" @success="canSucess"></upload-img>
    
        canSucess(file) {
            this.pngName = file.name;
            this.logoUrl = file.url;
         },
    

    我在父组件定义的canSuccess,这里我做的操作比较简单就是通过图片地址改变图片,同时改变图片的名字。这里也看你怎么玩!


    第一种效果

    当然我得通过这个组件把设置中的图片换掉所以引用即可

    相关文章

      网友评论

          本文标题:封装个vue上传图片小组件

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