element ui+七牛云上传

element ui 是一个非常简单强大的ui框架,今天分享一个upload上传图片到七牛云,代码比较长。

简单使用

<el-upload
  class="avatar-uploader"
  action="https://jsonplaceholder.typicode.com/posts/"
  :show-file-list="false"
  :on-success="handleAvatarSuccess"
  :before-upload="beforeAvatarUpload">
  <img v-if="imageUrl" :src="imageUrl" class="avatar">
  <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
<style>
  .avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }
  .avatar-uploader .el-upload:hover {
    border-color: #409EFF;
  }
  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
  }
  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }
</style>

<script>
  export default {
    data() {
      return {
        imageUrl: ''
      };
    },
    methods: {
      handleAvatarSuccess(res, file) {
        this.imageUrl = URL.createObjectURL(file.raw);
      },
      beforeAvatarUpload(file) {
        const isJPG = file.type === 'image/jpeg';
        const isLt2M = file.size / 1024 / 1024 < 2;

        if (!isJPG) {
          this.$message.error('上传头像图片只能是 JPG 格式!');
        }
        if (!isLt2M) {
          this.$message.error('上传头像图片大小不能超过 2MB!');
        }
        return isJPG && isLt2M;
      }
    }
  }
</script>

ps:实例在来自于官方文档

上传七牛云

1、七牛配置

import { getUrlAndToken } from '@api/sys.login' //获取token
import regionUphostMap from './config' // z0区
import day from 'dayjs'
// 获取七牛的地址,及token
export default {
  namespaced: true,
  state: {
    uploadUrl: '//upload.qiniup.com/',
    fileBaseUrl: '',
    qiNiuConfig: {
      key: 'openu/' + day().format('YYYY-MM-DD') + '/',
      token: '',
      config: {
        useCdnDomain: true,
        region: regionUphostMap.z0
      },
      putExtra: {
        fname: '', // 文件原名
        params: {}, // 用来放置自定义变量
        mimeType: [] || null // 文件类型限制
      }
    }
  },
  getters: {
    getQiNiuConfig: state => {
      return state.qiNiuConfig
    }
  },
  actions: {
    setQiNiu ({ commit }) {
      if (this.state.d2admin.user.info.name) {
        getUrlAndToken().then(res => {
          commit('setConfig', res)
        })
      }
    }
  },
  mutations: {
    setConfig (state, res) {
      state.fileBaseUrl = res.qiniu_url + '/'
      state.qiNiuConfig.token = res.token
    }
  }
}

2、vue组件中使用

<el-upload ref='upload' class="el-extend-upload" :action="uploadUrl" :data="qiNiuConfig"
               :before-upload="beforeUpload" :on-preview="onPreview" :file-list="fileList"
               :on-success="onSuccess" :on-remove="onRemove" :before-remove="beforeRemove" :on-exceed="handleExceed"
               :list-type="listType" :show-file-list="showFileList" :limit="fileLimit" :accept="fileType"
               v-bind="$attrs" :multiple="multiple">
      <i class="el-icon-plus"></i>
    </el-upload>

import day from 'dayjs' import { mapState } from 'vuex' import { randomString } from '@util/util' export default { name: 'el-extend-upload-image', mixins: [qiNiu, upload], inheritAttrs: false, props: { value: null, limit: { type: Number, default: 1 }, showFileList: { type: Boolean, default: true }, listType: { type: String, default: 'picture-card' }, imgSize: { type: String, default: '' }, fileSize: { type: Number, default: 0 }, fileType: { type: String, default: '' }, name: { type: String, default: '' }, multiple: { type: Boolean, default: false } }, data () { return { limitImgSize: this.imgSize, // 是否有图片尺寸限制 limitFileSize: this.fileSize, limitFileType: this.fileType, urls: [], imageUrl: '', fileList: [], fileLimit: this.limit, fileRule: [] } }, computed: { ...mapState('qiNiu', [ 'uploadUrl', 'fileBaseUrl', 'qiNiuConfig' ]), defaultTips () { let tips = '' let { limitImgSize, limitFileSize, limitFileType } = this if (limitImgSize) { tips += `建议上传${limitImgSize}的 ` } if (limitFileSize) { tips += `大小不要超过${limitFileSize}M ` } if (limitFileType) { tips += `仅支持${limitFileType}格式` } return tips }, imgRatio () { const { limitImgSize } = this let ratio = 1 if (limitImgSize) { const sizeArr = limitImgSize.split('*') const width = parseInt(sizeArr[0]) const height = parseInt(sizeArr[1]) ratio = width / height } return ratio } }, mounted () { this.setContainerSize() }, methods: { setContainerSize () { const el = this.$refs.upload if (this.listType !== 'picture-card' || !el) { return } const upload = el.$el.children[1] const height = upload.clientHeight const width = (height * this.imgRatio).toFixed(3) + 'px' // 修改预览图片大小 this.$nextTick(() => { upload.style.width = width setTimeout(() => { const fileList = el.$el.children[0].children[0] if (fileList) { fileList.style.width = width } }, 350) }) }, beforeUpload (file) { let arr = [] this.createKey(file) if (!this.multiple) { if (this.limitImgSize) { arr.push(this.checkImgSize(file)) } if (this.limitFileSize) { arr.push(this.checkFileSize(file)) } if (this.limitFileType) { arr.push(this.checkAccept(file)) } return this.promiseArr(arr) } }, createKey (file) { let fileSuffix = file ? file.name.substring(file.name.lastIndexOf('.')) : '' let fileType = file ? file.type.substring(0, file.type.lastIndexOf('/')) : '' this.qiNiuConfig.key = 'openu/' + fileType + '/' + day().format('YYYY-MM-DD') + '/' + randomString() + fileSuffix }, checkImgSize (file) { return new Promise((resolve, reject) => { let _URL = window.URL || window.webkitURL let img = new Image() img.src = _URL.createObjectURL(file) img.onload = () => { let valid = this.imgRatio === img.width / img.height let err = `图片${file.name}尺寸有误,请重新选择!` valid ? resolve(file) : reject(err) } }) }, checkFileSize (file) { return new Promise((resolve, reject) => { let err = `文件大小超过${this.limitFileSize}M,请重新选择!` let valid = file.size / 1024 / 1024 < this.limitFileSize valid ? resolve(file) : reject(err) }) }, checkAccept (file) { return new Promise((resolve, reject) => { let err = `文件类型不正确,请重新选择!` let valid = this.limitFileType.indexOf(file.type) === -1 valid ? reject(err) : resolve(file) }) }, async promiseArr (arr) { return Promise.all(arr).then(res => { return Promise.resolve(res) }).catch(err => { this.$message.error(err) return Promise.reject(err) }) }, deleteFile (file = {}) { let key = file ? file.key : null if (key) { let index = this.urls.find(item => { return item.indexOf(key) !== -1 }) this.urls.splice(index, 1) } this.emitInput() }, emitInput () { this.setContainerSize() if (this.limit > 1) { this.$emit('input', this.urls) this.$emit('change', this.urls) } else { let url = this.urls.length ? this.urls[0].url : '' this.$emit('input', url) this.$emit('change', url) } }, handleExceed (files, fileList) { this.$message.warning(`当前限制选择 ${this.limit} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`) }, beforeRemove (file, fileList) { if (file && file.status === 'success') { let name = file.name || '该文件' return this.$confirm(`确定移除 ${name}吗?`) } }, init () { if (this.value) { this.fileList = isString(this.value) ? [{ url: this.value }] : this.value } else { this.fileList = [] } }, onSuccess (response, file, fileList) { this.urls.push({ url: this.fileBaseUrl + response.key, name: file.name, ...response }) this.emitInput() if (this.multiple) { this.fileLimit *= 2 } }, onRemove (file, fileList) { if (file && file.status === 'success') { this.deleteFile(file) } }, } }

代码比较长,还是很简单就能看懂的

element ui+七牛云上传》有2个想法

评论已关闭。