準(zhǔn)備前
后臺(tái)項(xiàng)目:
后臺(tái)項(xiàng)目用的 vue+餓了么ui 框架
效果:
image.png
1.下載oss 插件
npm install ali-oss
- 封裝client.js文件:
const OSS = require('ali-oss');
export default function client() {
var client = new OSS({
region: 'oss-cn-guangzhou', // OSS所在的地域
accessKeyId: 'LTAI5tQ*******iXBYoWM', // 訪問密鑰ID
accessKeySecret: 'kpdSXYF**************w4X8uqsGA5', // 訪問密鑰Secret
bucket: 'jwlc', // 存儲(chǔ)桶(Bucket)的名稱
}) //后端提供數(shù)據(jù)
return client
}
- 封裝uploadOss.vue組件
<template>
<div class="upload-file">
<el-upload class="upload-demo" :drag="isDrag" ref="uploadItem" action="" :before-upload="beforeVideoUpload"
:show-file-list="false" :http-request="Upload">
<el-button v-if="!isDrag" size="small" type="primary">點(diǎn)擊上傳</el-button>
<template v-else>
<i class="el-icon-upload"></i>
<div class="el-upload__text">將文件拖到此處匹涮,或<em>點(diǎn)擊上傳</em></div>
</template>
<div class="el-upload__tip" slot="tip">
請(qǐng)上傳
<template v-if="fileSize"> 大小不超過 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
<template v-if="fileType"> 格式為 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
的文件
<template v-if="limit">蛉抓,最多上傳{{ limit }}個(gè)附件</template>
</div>
</el-upload>
<!-- 文件列表 -->
<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear"
tag="ul">
<li :key="file.url" class="el-upload-list__item ele-upload-list__item-content"
v-for="(file, index) in fileList">
<el-link :href="file.currentUrl" :underline="false" target="_blank">
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
</el-link>
<div class="ele-upload-list__item-content-action">
<el-link :href="file.currentUrl" :underline="false" target="_blank" type="primary">下載</el-link>
<el-link :underline="false" @click="handleDelete(index)" type="danger">刪除</el-link>
</div>
</li>
</transition-group>
</div>
</template>
<script>
import client from "./client.js"
export default {
name: 'Upload-oss',
props: {
// 值
value: [String, Object, Array],
// 數(shù)量限制
limit: {
type: Number,
default: 5,
},
// 大小限制(MB)
fileSize: {
type: Number,
default: 5,
},
// 文件類型, 例如['png', 'jpg', 'jpeg']
fileType: {
type: Array,
// default: () => ['txt', 'doc', 'docx', 'pdf', 'jpeg', 'png', 'xls', 'xlsx', 'ppt', 'pptx'],
default: null,
},
isDrag: {
type: Boolean,
default: true
}
},
watch: {
value: {
handler(val) {
if (val) {
let temp = 1;
// 首先將值轉(zhuǎn)為數(shù)組
const list = Array.isArray(val)
? val : Object.prototype.toString.call(val) == '[object Object]'
? [val] : this.value.split(',');
// 然后將數(shù)組轉(zhuǎn)為對(duì)象數(shù)組
this.fileList = list.map(item => {
if (typeof item === "string") {
item = { name: item, url: item };
}
item.uid = item.uid || new Date().getTime() + temp++;
return item;
});
} else {
this.fileList = [];
return [];
}
},
deep: true,
immediate: true
}
},
data() {
return {
videoUploadPercent: 0, // 上傳進(jìn)度
fileList: [],
}
},
async mounted() {
// 測(cè)試
const testUrl = '/test/2024/12/10/1733812864000.png'
const course = await client().get(testUrl)
console.log('course', course);
if (course.res) {
const sourceUrl = this.getUrl(course.res.data, course.res.headers['content-type'])
console.log('sourceUrl', sourceUrl);
}
},
methods: {
getUrl(binaryData, fileType) {
if (!binaryData) return ''
const blob = new Blob([binaryData], { type: fileType });
const sourceUrl = URL.createObjectURL(blob);
return sourceUrl;
},
Upload(file) {
console.log('Upload', file, file.file)
const fileEndName = file.file.name
const date = new Date()
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const formattedDate = `${year}/${month}/${day}/`;
const fileName = '/test/' + formattedDate +
`${Date.parse(new Date())}_` +
fileEndName //定義唯一的文件名
// client().put(fileName, file.file)
// 大文件上傳
client()
.multipartUpload(fileName, file.file, {
progress: (p) => {
//獲取進(jìn)度條的值
this.videoUploadPercent = Math.floor(p * 100)
}
})
.then(async (result) => {
console.log('result', result);
// const sourceUrl = this.getUrl(course.res.data, file.file.type)
// this.fileList.push({
// name: fileEndName,
// url: result.name,
// })
// console.log('sourceUrl', sourceUrl, this.fileList);
const course = await client().get(result.name)
if (course.res) {
const sourceUrl = this.getUrl(course.res.data, course.res.headers['content-type'])
this.fileList.push({
name: fileEndName,
url: result.name,
currentUrl: sourceUrl
})
this.$emit("input", this.fileList);
console.log('sourceUrl', sourceUrl, this.fileList);
}
})
.catch(err => {
console.log('oss err:', err);
})
},
//上傳視頻前
beforeVideoUpload(file) {
const isLt10M = file.size / 1024 / 1024 < 80
// 校檢文件類型
if (this.fileType) {
const fileName = file.name.split('.');
const fileExt = fileName[fileName.length - 1];
const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
if (!isTypeOk) {
this.$modal.msgError(`文件格式不正確, 請(qǐng)上傳${this.fileType.join("/")}格式文件!`);
return false;
}
}
if (!isLt10M) {
this.$modal.msgError('上傳視頻大小不能超過80MB哦!')
return false
}
return true
},
// 刪除文件
handleDelete(index) {
this.fileList.splice(index, 1);
this.$emit("input", this.fileList);
},
// 獲取文件名稱
getFileName(name) {
if (!name) return ''
// 如果是url那么取最后的名字 如果不是直接返回
if (name.lastIndexOf("/") > -1) {
return name.slice(name.lastIndexOf("/") + 1);
} else {
return name;
}
},
clearAll() {
this.fileList = []
}
}
}
</script>
<style lang="scss" scoped>
.upload-file-uploader {
margin-bottom: 5px;
}
.upload-file-list .el-upload-list__item {
border: 1px solid #e4e7ed;
line-height: 2;
margin-bottom: 10px;
position: relative;
}
.upload-file-list .ele-upload-list__item-content {
display: flex;
justify-content: space-between;
align-items: center;
color: inherit;
}
.ele-upload-list__item-content-action .el-link {
margin-right: 10px;
}
.upload-demo {
width: 100%;
}
.el-icon-document {
margin-left: 8px;
}
::v-deep .el-upload,
::v-deep .el-upload-dragger {
width: 100%;
}
</style>
- 頁面上引入組件
<el-dialog title="oss文件上傳" :visible.sync="isShow" width="500px" append-to-body>
<uploadOss v-model="fileList"></uploadOss>
</el-dialog>
阿里控制臺(tái)配置
-
創(chuàng)建Bucket
image.png
2.添加RAM 用戶賬號(hào)權(quán)限
image.png
2.1 oss權(quán)限全選添加
image.png
-
允許跨域
image.png