vite+vue3+minio

发布时间 2023-07-14 11:02:15作者: 幻影之舞

之前h5用的minio上传文件,现在web端也需要用这个,但h5是用的vue2, web用的vue3,就出现了一些问题

 架子是用的vite搭建的,但vite不支持require导入。用import的话minio不支持import引入,也会报错

一. 用vue2搭个项目,将minio通过require方式导入,再进行导出, 上传npm,然后再npm install 打的包就可以使用了

  可以在项目里直接安装,已经打包好的minio

npm install tz-minio-upload_beta

 这样就安装上了

 

使用方法:

  新建一个minio.js, 里面存放实例和方法,不废话,上代码

 

import axios from 'axios'
import { createMinioClient, fileToStream } from 'tz-minio-upload_beta'
import Calendar from './calendar'   // 处理时间的文件,下面有

const { VITE_minio_BUCKET_NAME, VITE_minio_endPoint, VITE_minio_port, VITE_minio_accessKey, VITE_minio_secretKey } = import.meta.env    // 开发环境的配置

const minioClient = createMinioClient({
    endPoint: VITE_minio_endPoint, // 地址
    port: Number(VITE_minio_port), // 端口号,若地址为类似test.minio.com,就不必写端口号
    useSSL: false,
    accessKey: VITE_minio_accessKey,
    secretKey: VITE_minio_secretKey,
})

// 生成minio对象名
const createKey = (fileName) => {
    var random = Math.floor(1000000 + Math.random() * 9000000)
    return `${Calendar.format(new Date(), 'yyyy/MM/dd')}_${random}_web_${fileName}`
}

// minio对象上传
const minioDownload = (Key) => {
    return new Promise(resolve => {
        minioClient.getObject(VITE_minio_BUCKET_NAME, Key, (err,  result) => {
            if (err || result.statusCode != 200) {
                resolve(null)
                return
            }
            resolve(result.url)
        })
    })
}

// minio对象上传
export const minioUpload = ({
        name, // 文件
        file
    }) => {
    return new Promise(resolve => {
        const type = file.type
        const size = file.size
        // 参数
        const metadata = {
            'content-type': type,
            'content-length': size
        }
        minioClient.bucketExists(VITE_minio_BUCKET_NAME, function (err) {
            if (err) {
                if (err.code == 'NoSuchBucket') {
                    return console.log('bucket does not exist.')
                }
                return console.log(err)
            } else {
                console.log('bucket exist.')
            }
            fileToStream(file, (data) => {
                let buf = data._readableState.buffer.head.data
                minioClient.putObject(VITE_minio_BUCKET_NAME, name, buf, size, metadata, (err, data) => {
                        if (err) {
                            resolve(null)
                            return
                        }
                        resolve(data)
                    }
                )
            })
        })
    })
}

// 上传文件
export const uploadFiles = async (
    // 文件
    file
) => {
    // 1. 检查上传文件必填
    if (file === void 0) {
        console.error('上传文件不能为空')
        return null
    }

    // 2. 生成上传对象名称
    var { name, type, size } = file
    var Key = createKey(name)
    // var Key = name

    // 3. 上传minio对象
    var isUpload = await minioUpload({ name: Key, file })
    if (isUpload === null) {
        return null
    }
    // 4. 下载上传对象,获取url
    var filePath = await minioDownload(Key)
    if (filePath === null) {
        return null
    }
    return {filePath, name}   // 返回服务器图片路径和图片名称, 可以按你想要的返回
}

 

.env.dev文件

# 开发环境下的配置文件
VITE_ENV = 'dev'
# minio桶名称
VITE_minio_BUCKET_NAME = '桶名称'
# 地址
VITE_minio_endPoint = '172.***.***.***'
# 端口
VITE_minio_port = ****
# 登录的accessKey
VITE_minio_accessKey = '6kD27b6oDOuYzt2'
# 登录的secretKey
VITE_minio_secretKey = 'y5kVAt4ti2ytXHjl0AjB77vC3YVY7Yd'
calendar.js
const ONE_DAY = 24 * 60 * 60 * 1000

// 星期名称map
const CHINESE_WEEK_MAP = {
  0: '星期天',
  1: '星期一',
  2: '星期二',
  3: '星期三',
  4: '星期四',
  5: '星期五',
  6: '星期六'
}

// 时间段
const TIME_SPACING_CHINESE = [
  {
    time: [1, 5],
    name: '凌晨'
  },
  {
    time: [5, 8],
    name: '早上'
  },
  {
    time: [8, 11],
    name: '上午'
  },
  {
    time: [11, 13],
    name: '中午'
  },
  {
    time: [13, 17],
    name: '下午'
  },
  {
    time: [17, 19],
    name: '傍晚'
  },
  {
    time: [19, 23],
    name: '晚上'
  },
  {
    time: [23, 24],
    name: '子夜'
  },
  {
    time: [0, 1],
    name: '子夜'
  }
]

const calendar = {
  // 一天时间秒数
  ONE_DAY,
  // 获取时间对象,默认获取当天
  getDateInfo(date) {
    return {
      year: date.getFullYear(),
      month: date.getMonth() + 1,
      day: date.getDate(),
      hour: date.getHours(),
      min: date.getMinutes(),
      second: date.getSeconds(),
      week: date.getDay()
    }
  },
  // 获取中文时间
  getDateChinese(date) {
    const result = this.getDateInfo(date)
    const timeInfo = TIME_SPACING_CHINESE.filter(item => {
      return result.hour >= item.time[0] && result.hour < item.time[1]
    })[0]
    return {
      ...result,
      weekChinses: CHINESE_WEEK_MAP[result.week],
      timeChinses: timeInfo.name
    }
  },
  // 格式化时间
  format(date, format) {
    var obj = this.getDateInfo(date)
    return format
      .replace('yyyy', this.prefixZero(obj.year))
      .replace('MM', this.prefixZero(obj.month))
      .replace('dd', this.prefixZero(obj.day))
      .replace('hh', this.prefixZero(obj.hour))
      .replace('mm', this.prefixZero(obj.min))
      .replace('ss', this.prefixZero(obj.second))
  },
  // 前置0
  prefixZero(value) {
    return Number(value) > 9 ? `${value}` : `0${value}`
  }
}

export default calendar

文件中使用:

  

<el-upload
        accept="image"
        class="avatar-uploader"
        :show-file-list="false"
        :before-upload="beforeAvatarUpload"
>
         <img v-if="imageUrl" :src="imageUrl" class="avatar" />
         <el-icon v-else class="avatar-uploader-icon"><Plus />    
         </el-icon>
</el-upload>



<script>

import { uploadFiles } from '@/utils/minio.js'
const imageUrl = ref('')
// 上传头像 
const beforeAvatarUpload = async (val) => {
   // val是上传的文件 await uploadFiles(val).then( imgInfo
=> {
     // filePath是minio上传成功后返回的图片路径 const { filePath }
= imgInfo formData.value.avatar = filePath imageUrl.value = filePath }) } </script>

这样就能拿到上传后的图片路径了,显示或者放到参数里都可以了

 

方法二

  使用大佬的minio-js, 开源地址