查看minio官網(wǎng),看到minio可以應(yīng)用在不同的環(huán)境下,這里著重講一下minio的js版,并在vue中運(yùn)行,并且增加上傳文件,增加文件類型,文件大小及數(shù)量,多文件上傳的需求
直接上代碼
首先在vue安裝minio
npm install --save minio
簡(jiǎn)單的講解一下代碼,本身minio是沒(méi)有文件類型篩選,文件大小和數(shù)量以及多文件這些功能;
這些其實(shí)是在input上實(shí)現(xiàn)的;
<input accept=".pdf,.doc" type="file" multiple="multiple" id="minIoFile" ref="minIoFile" v-show="false" @change="getFile">
文件類型是通過(guò)accept限制的;
多選文件是multiple;
文件大小和數(shù)量是通過(guò)其中的方法getFile實(shí)現(xiàn)的
然后強(qiáng)調(diào)一下minioClient,accessKey和secretKey是你登錄minio的用戶名和密碼 ;
然后直接上代碼
<template>
<div class="minioBox">
<el-button style="marginRight:10px;" @click="getFileName" size="mini" type="success">選擇文件</el-button>
<input accept=".pdf,.doc" type="file" multiple="multiple" id="minIoFile" ref="minIoFile" v-show="false" @change="getFile">
<el-button v-if="fileList.length>0" style="marginRight:10px;" @click="upload" size="mini" type="success">上傳</el-button>
<ul class="uploadFileList">
<li v-for="item,index of fileList" :key="index">
<span class="subString">{{item.name}}</span>
<span>({{(item.size/1024/1024).toFixed(2)}}M)</span>
<div class="floatRight" style="float: right;">
<i class="el-icon-close" style="cursor: pointer;" @click="deleteMinioFile(index)"></i>
</div>
</li>
</ul>
</div>
</template>
<script>
let Minio = require('minio')
let stream = require('stream')
//連接minio文件服務(wù)器
var minioClient = new Minio.Client({
endPoint: '', //對(duì)象存儲(chǔ)服務(wù)的URL
port: 9001,//端口號(hào)
useSSL: false, //true代表使用HTTPS
accessKey: '', //賬戶id
secretKey: '', //密碼
partSize: '20M'
});
export default {
data(){
return{
fileList:[],
}
},
methods: {
upload(){
this.fileList.map((item,index) => {
this.uploadMinIo(item,index);
})
},
deleteMinioFile(index){
this.fileList.splice(index,1)
},
getFileName(){
let inputDOM = this.$refs.minIoFile;
inputDOM.click();
},
getFile(event){
console.log(document.getElementById('minIoFile').files);
let files = document.getElementById('minIoFile').files;
let arr = [];
let fileSwitch = true;
if(files.length > 0){
for(let i = 0;i<files.length;i++){
if((files[i].size/1024/1024).toFixed(2)>64){
this.$message({
message: `${item.name}超過(guò)文件的最大長(zhǎng)度`,
type: 'warning'
});
fileSwitch = false;
}
}
if(fileSwitch){
for(let i = 0;i<files.length;i++){
console.log(files[i][File]);
this.fileList.push(files[i])
}
}
}
},
//上傳文件
uploadMinIo(fileObj,index) {
let vm = this
// const files = fileObj;
if (fileObj) {
let file = fileObj
//判斷是否選擇了文件
if (file == undefined) {
//未選擇
console.log("請(qǐng)上傳文件")
} else {
//選擇
//獲取文件類型及大小
const fileName = file.name
const mineType = file.type
const fileSize = file.size
//參數(shù)
let metadata = {
"content-type": mineType,
"content-length": fileSize
}
//判斷儲(chǔ)存桶是否存在
minioClient.bucketExists('testfile', function(err) {
if (err) {
if (err.code == 'NoSuchBucket') return console.log("bucket does not exist.")
return console.log(err)
}
//存在
console.log('Bucket exists.')
//準(zhǔn)備上傳
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = function (e) {
const dataurl = e.target.result
//base64轉(zhuǎn)blob
const blob = vm.toBlob(dataurl)
//blob轉(zhuǎn)arrayBuffer
let reader2 = new FileReader()
reader2.readAsArrayBuffer(blob)
reader2.onload = function(ex) {
//定義流
let bufferStream = new stream.PassThrough();
//將buffer寫入
bufferStream.end(new Buffer(ex.target.result));
//上傳
minioClient.putObject('testfile', fileName, bufferStream, fileSize, metadata, function(err, etag) {
if (err == null) {
minioClient.presignedGetObject('testfile', fileName, 24*60*60, function(err, presignedUrl) {
if (err) return console.log(err)
//輸出url
console.log(presignedUrl)
// this.$notify({
// title: '標(biāo)題名稱',
// message: h('i', { style: 'color: teal'}, '這是提示文案這是提示文案這是提示文案這是提示文案這是提示文案這是提示文案這是提示文案這是提示文案')
// });
})
}
//return console.log(err, etag)
})
}
}
})
}
}
},
//base64轉(zhuǎn)blob
toBlob (base64Data) {
let byteString = base64Data
if (base64Data.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(base64Data.split(',')[1]) // base64 解碼
} else {
byteString = unescape(base64Data.split(',')[1])
}
// 獲取文件類型
let mimeString = base64Data.split(';')[0].split(":")[1] // mime類型
// ArrayBuffer 對(duì)象用來(lái)表示通用的开呐、固定長(zhǎng)度的原始二進(jìn)制數(shù)據(jù)緩沖區(qū)
// let arrayBuffer = new ArrayBuffer(byteString.length) // 創(chuàng)建緩沖數(shù)組
// let uintArr = new Uint8Array(arrayBuffer) // 創(chuàng)建視圖
let uintArr = new Uint8Array(byteString.length) // 創(chuàng)建視圖
for (let i = 0; i < byteString.length; i++) {
uintArr[i] = byteString.charCodeAt(i)
}
// 生成blob
const blob = new Blob([uintArr], {
type: mimeString
})
// 使用 Blob 創(chuàng)建一個(gè)指向類型化數(shù)組的URL, URL.createObjectURL是new Blob文件的方法,可以生成一個(gè)普通的url,可以直接使用,比如用在img.src上
return blob
}
}
}
</script>
<style lang="scss" scoped>
.minioBox{
color: #000000;
padding: 10px;
width: 90%;
.uploadFileList {
width: 100%;
li {
height: 22px;
line-height: 22px;
margin: 10px 0px;
span {
margin-right: 10px;
vertical-align: top;
}
.subString {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 53%;
display: inline-block;
}
i {
margin: 5px 5px 0 0;
}
.el-icon-close,
.el-icon-upload-success {
float: right;
}
.upload-success {
color: green;
}
.upload-fail {
color: red;
}
}
li:hover {
background-color: #f5f7fa;
}
li:first-child {
margin-top: 10px;
}
/deep/ .progress {
margin-top: 2px;
width: 200px;
height: 14px;
margin-bottom: 10px;
overflow: hidden;
background-color: #f5f5f5;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
display: inline-block;
.progress-bar {
background-color: rgb(92, 184, 92);
background-image: linear-gradient(
45deg,
rgba(255, 255, 255, 0.14902) 25%,
transparent 25%,
transparent 50%,
rgba(255, 255, 255, 0.14902) 50%,
rgba(255, 255, 255, 0.14902) 75%,
transparent 75%,
transparent
);
background-size: 40px 40px;
box-shadow: rgba(0, 0, 0, 0.14902) 0px -1px 0px 0px inset;
box-sizing: border-box;
color: rgb(255, 255, 255);
display: block;
float: left;
font-size: 12px;
height: 20px;
line-height: 20px;
text-align: center;
transition-delay: 0s;
transition-duration: 0.6s;
transition-property: width;
transition-timing-function: ease;
width: 266.188px;
}
}
}
}
</style>