使用阿里云上传先看官方文档(阿里云官方文档)
我这边只做了简单上传和分片上传,也包含了粘贴上传和拖拽上传。
1.首页先安装
npm i ali-oss
2.在utils下创建uploadOss.js
const OSS = require('ali-oss')
import { getOsstoken } from '@/api/index'
//把file文件转为base64
function getBase64(file) {
return new Promise((resolve, reject) => {
///FileReader类就是专门用来读文件的
const reader = new FileReader()
//开始读文件
//readAsDataURL: dataurl它的本质就是图片的二进制数据, 进行base64加密后形成的一个字符串,
reader.readAsDataURL(file)
// 成功和失败返回对应的信息,reader.result一个base64,可以直接使用
reader.onload = () => resolve(reader.result)
// 失败返回失败的信息
reader.onerror = error => reject(error)
})
}
//获取文件大小
function getfileSize(val) {
if (val === 0) return "0 B"
var k = 1024;
var sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
let i = Math.floor(Math.log(val) / Math.log(k))
return ((val / Math.pow(k, i)).toFixed(2) + "" + sizes[i])
}
//时间格式转换
function parseTime(time, pattern) {
if (arguments.length === 0 || !time) {
return null
}
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
//阿里云分片上传
function uploadOssMultipart(file, options) {
return new Promise(async (resolve, reject) => {
getOsstoken().then(res => {
if (res.code == 1) {
const client = new OSS({
secure: res.data.secure, // 上传链接返回支持https
region: res.data.region, // 填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
accessKeyId: res.data.AccessKeyId,
accessKeySecret: res.data.AccessKeySecret,
bucket: res.data.bucket, // 填写Bucket名称
stsToken: res.data.SecurityToken //上传token
})
// 唯一的文件名这个规则需要在阿里云哪里配置好
const fileName = '/uploads/' + parseTime(file.lastModifiedDate, '{y}{m}{d}/') + file.fileName + file.lastModified
resolve(client.multipartUpload(fileName, file.file, { ...options }))
}
})
})
}
//阿里云普通上传
function uploadOssPut(file) {
return new Promise(async (resolve, reject) => {
getOsstoken().then(res => {
if (res.code == 1) {
const client = new OSS({
secure: res.data.secure, // 上传链接返回支持https
region: res.data.region, // 填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
accessKeyId: res.data.AccessKeyId,
accessKeySecret: res.data.AccessKeySecret,
bucket: res.data.bucket, // 填写Bucket名称
stsToken: res.data.SecurityToken
})
const fileName = '/uploads/' + parseTime(file.lastModifiedDate, '{y}{m}{d}/') + file.name
// 配置路径以及文件名称
resolve(client.put(fileName, file))
}
})
})
}
export { uploadOssPut, uploadOssMultipart,getfileSize,getBase64}
3.普通上传方法使用
import { uploadOssPut } from '@/utils/uploadOss.js';
<div class="btn" @click="setAvatar">修改头像</div>
<input type="file" ref="file" style="display: none;" v-on:change="handleDrop($event)">
setAvatar() {
this.$refs.file.click()
},
async handleDrop(e) {
let files = e.target.files[0]
let url = await uploadOssPut(files)
saveUserInfo({ avatar: '/' + url.name }).then(res => {
if (res.code == 1) {
this.$modal.msgSuccess(`头像已修改`);
this.getuser()
}
})
},
4.分片上传以及拿到上传进度支持多文件
<template>
<div>
<input type="file" multiple ref="file" style="display: none;" v-on:change="handleUpload($event)">
<div @click="getFile">
点击上传
</div>
<div v-if="isupload">
<div v-for="(item, index) in filelist " :key="index" style="display: flex;margin-bottom:10px">
<div>{{ item.fileName }}</div>
<div style="margin:0px 10px;width:100px">{{ item.fileSize }}</div>
<el-progress style="width:150px" :text-inside="true" :stroke-width="20"
:percentage="item.progress"></el-progress>
</div>
</div>
</div>
</template>
<script>
import { uploadOssMultipart, getfileSize } from '@/utils/uploadOss.js';
export default {
name: '',
data() {
return {
filelist: [],
isupload: false,
nowlist: []
}
},
methods: {
getFile() {
this.$refs.file.click()
},
handleUpload(e) {
let files = e.target.files
for (let i = 0; i < files.length; i++) {
let obj = {
file: files[i],
fileName: files[i].name,
fileSize: getfileSize(files[i].size),
lastModifiedDate: files[i].lastModifiedDate,
progress: 0
}
this.filelist.push(obj)
}
this.uploadOss()
},
async uploadOss() {
console.log(this.filelist);
this.filelist.forEach(item => {
const options = {
// 获取分片上传进度、断点和返回值。
progress: (p, cpt, res) => {
item.progress = Number((p * 100).toFixed(0));//进度条
},
// 目前不传Content-Type 发现会出现错误,具体原因不清除
headers: {
'Content-Type': 'Content-Type(Mime-Type)'
},
partSize: 1024 * 1024 * 1,
};
this.isupload = true
uploadOssMultipart(item, options).then(res => {
var url = ''
let index = res.res.requestUrls[0].indexOf("?");
if (index == -1) {
url = res.res.requestUrls[0]
} else {
url = res.res.requestUrls[0].substring(0, index)
}
this.$refs.file.value = ''
this.nowlist.push(url)
console.log(this.nowlist, '22222');
})
})
},
},
}
</script>
<style lang='scss' scoped></style>
5.支持拖拽粘贴上传
拖拽和复制与点击上传区别不大,只是拿到file时的位置不同。
<input type="textarea" style="width: 300px;height:200px;border:1px solid #eee" @drop.prevent="handleUpload" @paste.prevent="handleUpload">
handleUpload(e) {
let files;
if (e.type == 'drop') {//拖拽
e.preventDefault()
files = e.dataTransfer.files;
} else if (e.type == 'paste') {//复制
files = e.clipboardData.files;
} else if (e.type == 'change') { //点击
files = e.target.files
}
for (let i = 0; i < files.length; i++) {
let obj = {
file: files[i],
fileName: files[i].name,
fileSize: getfileSize(files[i].size),
lastModifiedDate: files[i].lastModifiedDate,
progress: 0
}
this.filelist.push(obj)
}
this.uploadOss()
},