基於nuxt和iview搭建OM後臺管理系統實踐(4)-七牛上傳元件的封裝

願愛無憂dk_發表於2018-07-09

封面圖,基於創客貼線上製作

目錄結構

這是《基於nuxt和iview搭建OM後臺管理系統實踐》這一個系列文章的目錄,大致思路如下:

前言

上一篇記錄了阿里oss上傳元件的封裝過程,這一篇開始講解七牛上傳元件的封裝。原本計劃上傳元件用一篇文章來寫,發現程式碼有點多,索性就分兩篇來寫。

看東西

如動圖所示,為七牛上傳元件演示,可以看到元件有上傳、預覽、刪除重新上傳等功能。(功能與前面阿里oss上傳元件相同)

七牛上傳元件演示

七牛上傳元件實現過程

其實這裡的封裝很簡單,直接用的ivivew提供的upload元件,翻閱iview文件發現可以在upload元件的data屬性裡傳七牛token即可完成上傳功能。然後token值官方推薦後端生成,google一下發現github上有人封裝了npm包(qiniu-uptoken),可以不需要後端支援直接在前端生成token,簡直爽歪歪咯,誰叫我不會後端呢,哈哈哈哈!此處我想給自己一個尷尬而不失禮貌的微笑?

iview upload說明文件

完整程式碼

// 檔案componets/qiniu-upload.vue
<template>
<div>
  <div class="demo-upload-list" v-for="(item,index) in uploadList" :key="index">
        <template v-if="item.status === 'finished'">
            <img :src="item.url">
            <div class="demo-upload-list-cover">
                <Icon type="ios-eye-outline" @click.native="handleView(item.name)"></Icon>
                <Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
            </div>
        </template>
        <template v-else>
            <Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
        </template>
    </div>
    <Upload   
        ref="upload"
        :show-upload-list="false"
        :default-file-list="defaultList"
        :on-success="handleSuccess"
        :format="['jpg','jpeg','png']"
        :max-size="maxSize"
        :on-format-error="handleFormatError"
        :on-exceeded-size="handleMaxSize"
        :before-upload="handleBeforeUpload"
        :multiple="!multiple"
        type="drag"
        :data="uptoken"
        :action="actionUrl"
        :style="{'display': 'inline-block','width':width}">
        <div :style="{'width': width,'height':height,'line-height': '58px'}" v-if="multiple&&uploadList.length==0">
            <Icon type="camera" size="20"></Icon>
        </div>
    </Upload>
    <Modal title="圖片預覽" v-model="visible">
        <img :src="picHostName + imgName" v-if="visible" style="width: 100%">
    </Modal>
</div>
</template>
<script>
import {qiniuConfig} from '~/config';//七牛配置
const QiniuUPToken = require('qiniu-uptoken');//引入前端生成七牛token的包

export default {
  props:{
    maxSize:{
      type:Number,
      default:2048
    },
    multiple:{
      type:Boolean,
      default:true
    },
    width:{
      default:"58px"
    },
    height:{
      default:'58px'
    }
  },
  data() {
    return {
      defaultList: [],
      imgName: "",
      picHostName:qiniuConfig.pic_hostname,
      visible: false,
      uploadList: [],
      uptoken:{},
      actionUrl:qiniuConfig.action_url,
      fileList:[]
    };
  },
  methods: {
    getToken(){
      this.uptoken.token = QiniuUPToken(qiniuConfig.access_key,qiniuConfig.secret_key,qiniuConfig.bucketname);   
    },
    handleView(name) {
      this.imgName = name;
      this.visible = true;
    },
    handleRemove(file) {
      const fileList = this.$refs.upload.fileList;
      this.$refs.upload.fileList.splice(fileList.indexOf(file), 1);
    },
    handleSuccess(res, file) {
      // console.log(res);
      file.url = qiniuConfig.pic_hostname+res.key;
      file.name = res.key;
      this.$emit('handleSuccess',qiniuConfig.pic_hostname+res.key);//傳遞給父元件
    },
    handleFormatError(file) {
      this.$Notice.warning({
        title: "上傳的格式不正確",
        desc:
          "檔案'" +
          file.name +
          "'不合法, 請重新選擇jpg or png.的格式"
      });
    },
    handleMaxSize(file) {
      this.$Notice.warning({
        title: "檔案大小超出限制",
        desc: "檔案'" + file.name + "'大小超出"+this.maxSize/1024+'M限制'
      });
    },
    handleBeforeUpload() {
      const check = this.uploadList.length < 5;
      if (!check) {
        this.$Notice.warning({
          title: "最多隻能上傳五張圖片"
        });
      }
      return check;
    }
  },
  mounted() {
    this.getToken();
    this.uploadList = this.$refs.upload.fileList;
  }
};
</script>
<style>
.demo-upload-list {
  display: inline-block;
  width: 60px;
  height: 60px;
  text-align: center;
  line-height: 60px;
  border: 1px solid transparent;
  border-radius: 4px;
  overflow: hidden;
  background: #fff;
  position: relative;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
  margin-right: 4px;
}
.demo-upload-list img {
  width: 100%;
  height: 100%;
}
.demo-upload-list-cover {
  display: none;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.6);
}
.demo-upload-list:hover .demo-upload-list-cover {
  display: block;
}
.demo-upload-list-cover i {
  color: #fff;
  font-size: 20px;
  cursor: pointer;
  margin: 0 2px;
}
</style>
複製程式碼

使用方法:按照vue標準引用區域性元件的方式引入即可,呼叫handleSuccess方法即可獲取上傳完成的url。在此推薦寫一個箭頭回撥函式(如下),這樣在一個頁面有多個引用的時候可以減少很多冗餘程式碼。

<qiniu-upload
    @handleSuccess = "(url) => this.formItem.litpic = url">
</qiniu-upload>
複製程式碼

總結

  • 坦率來講這個元件不叫封裝,其實就只做了一件最核心的事情,那就是在前端生成七牛token。
  • 儘管iview有一些坑,但不得不說其使用者體驗做得是非常不錯的,通過檢視其原始碼也學到了很多東西,比如程式碼規範、前端使用者體驗,iview都做得蠻出色的,在此安利一波iview

系列文章連結

以下為本系列的文章合集,在此列出便於查閱:

相關文章