项目使用 Ruoyi-Vue 搭建

效果展示

一、后端(Java、SpringBoot)

省略maven、配置等操作……详细点击 springboot整合七牛云——前端获取凭证token,用户客户端直传七牛服务、服务端上传

接口展示

在这里插入图片描述

二、前端

1.创建组件

在这里插入图片描述

2.组件代码

<template>
  <el-tabs v-model="tabsActiveName" :tab-position="tabPosition">
    <el-tab-pane label="本地上传" name="local">
      <el-upload
        :limit="euFileLimit"
        :class="{hide: hideUpload}"
        :data="euHeaders"
        :multiple="euMultiple"
        :accept="euAccept"
        :list-type="euListType"
        :file-list="euFileList"
        :action="euAction"
        :before-upload="beforeFileUpload"
        :on-error="handleFileError"
        :on-change="handleFileChange"
        :on-remove="handleFileRemove"
        :on-success="handleFileSuccess"
      >
        <i class="el-icon-plus"></i>
      </el-upload>
    </el-tab-pane>
    <el-tab-pane label="网络抓取" name="fetchNet" v-if="euFileLimit===1">
      <el-input :disabled="hideUpload"
                v-model="temporaryInput"
                @focus="getInputFullFocus($event)"
                placeholder="复制网络文件的 http 地址">
        <el-tooltip slot="prepend" content="本地上传栏下存在已上传完成的文件时,网络抓取不可操作,如需操作,请将前一项的文件移除" placement="top">
          <i class="el-icon-question"></i>
        </el-tooltip>
        <el-button :disabled="hideUpload" slot="append" icon="el-icon-upload" @click="fetchNetSource">抓取
        </el-button>
      </el-input>
    </el-tab-pane>
  </el-tabs>
</template>

<style scoped>
.hide .el-upload--picture-card {
  display: none;
}
</style>
<script>
import { getInputFullFocus } from '@/api/tool/inputTool'
import { fetchNetSource, qiniuPolicy } from '@/api/upload/upload'

export default {
  name: 'uploadQiNiu',
  props: {
    //标签页的位置 left|right|top|bottom
    tabPosition: { type: String, default: 'top' },
    //文件http链接的域名,在获取七牛token时由后台传来
    fileDomain: { type: String, default: '' },
    //限制上传文件数
    euFileLimit: { type: Number, default: 1 },
    //请求七牛上传时附带的请求头
    euHeaders: {
      type: Object,
      default() {
        return {}
      }
    },
    //el-upload 的 文件列表
    euFileList: {
      type: Array,
      default() {
        return []
      }
    },
    //接受的文件格式,具体到 .xxx,可以让打开的文件选择框里只有指定的文件,所有beforeUpload方法没做二次校验
    euAccept: { type: String, default: '' },
    //是否允许多选文件
    euMultiple: { type: Boolean, default: false },
    //文件展示样式
    euListType: { type: String, default: 'picture-card' },
    //上传的地址
    euAction: { type: String, default: 'https://upload.qiniup.com/' },
    //父页面 需要被赋值的目标属性
    targetUrl: { type: String, default: '' }
  },
  data() {
    return {
      //切换标签时的子标签名字,默认local本地上传,上传数euFileLimit大于1时,就只有本地上传
      tabsActiveName: 'local' ,
      //控制当上传到euFileLimit所限定的数时,上传加号框隐藏
      hideUpload:  false ,
      //网络抓取的input框的临时值存放
      temporaryInput: null,
    }
  },
  methods: {
    //input框自动全选其内容,从js引入的方法,在此声明一下,html方可使用
    getInputFullFocus,
    //抓取网络文件资源
    fetchNetSource() {
      let data = { url: this.temporaryInput }
      fetchNetSource(data).then(response => {
        this.$emit('monitorFileSuccess',response.data.key)
        this.$emit('monitorRefreshFileList',response.data.key)
        this.tabsActiveName = 'local'
      })
    },
    //文件状态改变时
    handleFileChange(file, fileList) {
      //上传选择框是否隐藏 取决于 当前文件列表长度是否大于等于限制文件数
      this.hideUpload = fileList.length >= this.euFileLimit
    },
    //文件移除
    handleFileRemove(file, fileList) {
      this.hideUpload = fileList.length >= this.euFileLimit
      this.$emit('monitorFileRemove', file)
    },
    //文件上传失败
    handleFileError() {
      this.$modal.msgError('文件上传失败,请稍后再试')
    },
    //文件上传成功
    handleFileSuccess(response, file, fileList) {
      //通知父组件,文件上传成功,结果在父组件向子组件的props属性赋值
      this.$emit('monitorFileSuccess',this.fileDomain + response.key)
    },
    // 文件上传前
    beforeFileUpload(file) {
      return new Promise((resolve, reject) => {
        //上传前获取七牛token等信息
        qiniuPolicy().then(response => {
          //七牛域名 传给父组件,让父组件对 自己的 data里的数据进行修改
          this.$emit('monitorFileDomain',response.data.url)
          //请求七牛前 组装headers
          this.euHeaders.token = response.data.token
          this.euHeaders.key = response.data.dirPrefix + this.getUUID() + '.' + file.name.substring(file.name.lastIndexOf('.') + 1)
          resolve(true)
        }).catch(error => {
          console.log('文件上传出错:' + error)
          reject(false)
        })
      })
    },
    //生成uuid以作文件名
    getUUID() {
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
        return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
      })
    }
  }
}
</script>

2.组件 import 的接口等功能

2.1-InputTool.js

//点击input框,自动全选其内容
export function getInputFullFocus(event){
  event.currentTarget.select();
}

2.2-Upload.js

import request from '@/utils/request'

// 七牛token
export function qiniuPolicy(query) {
  return request({
    url: '/thirdPart/qiniu/policy',
    method: 'get',
    params: query
  })
}

//抓取网络资源
export function fetchNetSource(data) {
  return request({
    url: '/thirdPart/qiniu/fetchNetSource',
    method: 'post',
    data: data
  })
}

3.注册组件

main.js中加入一下代码

//自定义七牛上传组件
import uploadQiNiu from '@/components/Upload/uploadQiNiu'

Vue.use(uploadQiNiu)

4.使用组件

4.1-引入组件 并 声明属性

import UploadQiNiu from '@/components/Upload/uploadQiNiu'
export default {
	…………
	components: {
    	uploadQiNiu: UploadQiNiu
  	},
  	data() {
    	return {
      		//七牛云上传 子组件参数
      		fileLimit: 1,
      		fileDomain: null,
      		fileList: [],
      		}
      },
  }

4.2-使用组件标签

在这里插入图片描述

<upload-qi-niu eu-accept=".JPG, .PNG, .JPEG,.jpg, .png, .jpeg"
               :eu-file-limit="fileLimit"
               :eu-file-list="fileList"
               eu-list-type="picture-card"
               :eu-multiple="false"
               tab-position="top"
               :target-url="form.icon"
               :file-domain="fileDomain"
               @monitorFileSuccess="monitorFileSuccess"
               @monitorFileDomain="monitorFileDomain"
               @monitorRefreshFileList="monitorRefreshFileList"
               @monitorFileRemove="monitorFileRemove"
               ref="uploadQiNiu"></upload-qi-niu>

4.3-创建方法

methods: {
    //监听七牛云上传子组件得到的 文件域名值,并在父组件对子进行修改
    monitorFileDomain(url) {
      this.fileDomain = url
    },
    // 监听七牛云上传子组件文件上传成功,修改网络抓取输入框框里的值,form表单icon赋值
    monitorFileSuccess(url) {
      this.$refs.uploadQiNiu.temporaryInput = url
      this.form.icon = url
    },
    //监听七牛云上传子组件 刷新el-upload组件的文件集合
    monitorRefreshFileList(url) {
      this.fileList = []
      if (url != null) {
        this.fileList.push({ url: url })
      }
      this.$refs.uploadQiNiu.handleFileChange(null, this.fileList)
    },
    //监听文件移除
    monitorFileRemove(file) {
      this.form.icon = null
    },
}

4.4-修改自带的 表单重置方法

// 表单重置
    reset() {
      this.form = {
        menuId: null,
       	.......
       	.......
        .......
      }
      this.resetForm('form')
      //对七牛云上传文件子组件的操作,
      //其它方法默认已经调用reset()方法,改在这里省事
      this.fileList = []
      setTimeout(() => {
        //给vue点时间,否则 ref 子组件为空
        this.$refs.uploadQiNiu.temporaryInput = null
        this.$refs.uploadQiNiu.handleFileChange(null, this.fileList)
        this.$refs.uploadQiNiu.tabsActiveName = 'local'
      }, 500)
    },

4.5-修改自带的 修改按钮操作方法

在这里插入图片描述

/** 修改按钮操作 */
    handleUpdate(row) {
      this.reset()
      this.getTreeselect()
      if (row != null) {
        this.form.menuId = row.menuId
      }
      getMenu(row.menuId).then(response => {
        this.form = response.data
        //添加的代码
        if (response.data.icon !== null) {
          //对七牛云上传文件子组件的操作
          this.fileList = [{ url: response.data.icon }]
          setTimeout(()=>{
            //给vue点时间,否则 ref 子组件为空
            this.$refs.uploadQiNiu.handleFileChange(null, this.fileList)
            this.$refs.uploadQiNiu.temporaryInput = response.data.icon
          },500)
        }
        this.open = true
        this.title = '修改角色权限'
      })
    },
Logo

快速构建 Web 应用程序

更多推荐