父组件引用
<el-form-item label="视频封面:" prop="img" class="top_10">
<ImageUpolad v-model="videoUploadFrom.img" :imgType="['jpg', 'jpeg', 'png']" size="" @uploadEvt="uploadEvt" :disabled="typeVideo === '3'" />
</el-form-item>
import ImageUpolad from '@/components/imageUpolad'
components: { ImageUpolad },
// 图片 上传
uploadEvt(url) {
this.videoUploadFrom.img = url
},
子组件
<template>
<div class="">
<el-upload
class="avatar-uploader"
action="#"
:show-file-list="false"
:http-request="upLoaderFun"
:before-upload="beforeAvatarUpload"
accept=".jpg,.png,.gif,.jpeg,.JPG,.PNG,.GIF,.JPEG"
:disabled="upload || disabled"
>
<div v-if="imageUrl" class="avatar">
<i class="el-icon-error" @click="deleteEvt"></i>
<img :src="imageUrl" class="avatars" />
</div>
<div v-else class="avatar-uploader-icon">
<div class="icon_clone"></div>
<span class="span_1">
点击选择
<span class="center1">本地文件</span>
上传文件
</span>
<span class="span_2">支持 {{ uploadType }} 格式,{{ imageSize ? ` ${imageSize[0]}px*${imageSize[1]}px ,` : '' }}{{file_size}}以内</span>
</div>
</el-upload>
</div>
</template>
<script>
import { uploadImg } from '@/utils/tool'
export default {
name: 'ImageUpolad',
props: {
value: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
},
imgType: {
typee: Array,
default: () => {
return ['jpg', 'png', 'jpeg']
}
},
size: {
type: String,
default: ''
},
maxSize: {
type: Number,
default: 1024
}
},
data() {
return {
uploadType: '',
imageSize: '',
imageUrl: this.value
}
},
computed: {
upload() {
if (!this.imageUrl) return false
return true
},
file_size() {
if (this.maxSize >= 1024) {
return (this.maxSize / 1024).toFixed(2) + 'MB'
} else {
return this.maxSize + 'KB'
}
},
},
watch: {
value(newV) {
this.imageUrl = newV
}
},
mounted() {
this.uploadType = this.imgType.join('、')
this.imageSize = this.size ? this.size.split('*') : ''
},
methods: {
upLoaderFun({ file }) {
uploadImg(file).then((res) => {
if (res.code === 1) {
this.$emit('uploadEvt', res.data)
} else {
this.$message.error('上传图片失败')
}
})
},
beforeAvatarUpload(file) {
if (file.size / 1024 > this.maxSize) {
this.$message.error(`请上传指定大小内的图片!`)
return false
}
if (this.size) {
const _this = this
const isSize = new Promise((resolve, reject) => {
// const width = 5120
// const height = 2880
const width = this.imageSize[0] - 0 // 限制图片尺寸
const height = this.imageSize[1] - 0
const _URL = window.URL || window.webkitURL
const img = new Image()
img.onload = () => {
const valid = img.width === width && img.height === height
valid ? resolve() : reject()
}
img.src = _URL.createObjectURL(file)
}).then(
() => {
return file
},
() => {
_this.$message.error('请上传标准格式宽高的图片')
return Promise.reject()
}
)
return isSize
}
},
deleteEvt() {
this.$emit('uploadEvt', '')
}
}
}
</script>
<style lang='scss' scoped>
/deep/.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
/deep/.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
/deep/.avatar-uploader-icon {
font-size: 14px;
width: 400px;
height: 200px;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px 0;
justify-content: space-evenly;
.icon_clone {
display: block;
width: 36px;
height: 48px;
border: 4px solid #cccccc;
}
.span_1 {
color: #666666;
.center1 {
color: #409eff;
}
}
.span_2 {
font-size: 14px;
color: #cccccf;
}
}
/deep/.avatar {
width: 400px;
height: 200px;
display: block;
position: relative;
.el-icon-error {
display: none;
}
&:hover {
.el-icon-error {
display: block;
position: absolute;
right: 10px;
top: 10px;
font-size: 20px;
}
}
.avatars {
width: 400px;
height: 200px;
}
}
</style>
OSS上传js
// OSS上传类型
const dataObjectType = [
// 文件
{
// 有效类型
validType(dataObject) {
if (!(dataObject instanceof File)) return false;
return true;
},
// 有效长度
async validSize(dataObject, maxSize) {
await vaildFileSize(dataObject, maxSize);
},
async upload(client, dataObject) {
const [p, ...names] = dataObject.name.split(".").reverse();
let file_name = `${names.reverse().join('.')}_w${new Date().getTime()}.${p}`;
return await client.multipartUpload(file_name, dataObject, {})
},
},
// blob
{
// 有效类型
validType(dataObject) {
if (!(dataObject instanceof Blob)) return false;
return true;
},
// 有效长度
async validSize(dataObject, maxSize) {
await vaildFileSize(dataObject, maxSize);
},
async upload(client, dataObject, filetype) {
return new Promise((res, rej) => {
let file_name = `w${new Date().getTime()}.${filetype}`;
const fileReader = new FileReader();
fileReader.onload = (e) => {
const buffer = new OSS.Buffer(e.target.result);
res(client.put(file_name, buffer, {}));
};
fileReader.readAsArrayBuffer(dataObject);
});
},
},
];
// 验证文件大小
export function vaildFileSize(obj, maxSize) {
return new Promise((res, rej) => {
// 限制大小
if (maxSize >= 0 && maxSize < obj.size) {
rej();
} else {
res();
}
});
}
export function uploadImg(file, options={}) {
return UploadOSS(file, options)
.then(({url, name}) => {
return {
code: 1,
data: url,
};
})
}
export async function UploadOSS(dataObject, options={}) {
console.log('dataObject', dataObject, '---', options)
const maxSize = options.maxSize || maxUploadFileSize;
const overMaxSizeMsg = options.overMaxSizeMsg || `文件大小不能超过${formatDataSize(maxSize)}`
let dataObjectT;
if (!dataObjectType.some(item => item.validType(dataObject) ? dataObjectT = item : false)) throw new Error("数据类型错误");
try {
await dataObjectT.validSize(dataObject, maxSize)
} catch (error) {
if (!options.notWarning) {
vue.$message.warning(overMaxSizeMsg);
console.warn(error);
}
throw new Error(overMaxSizeMsg);
}
const results = await managerUpload(dataObject)
console.log('results', results)
sessionStorage.setItem('fileName', results.name)
return results
}
export function managerUpload(file) {
const protocol = window.location.protocol
var sendData = new FormData();
sendData.append('appcode',sessionStorage.getItem('appcode'));
sendData.append('v','manager');
sendData.append('alias','manager_upload');
sendData.append('file',file);
sendData.append('admin_id',sessionStorage.getItem('admin_id'));
sendData.append('key',sessionStorage.getItem('key'));
return new Promise((resolve, reject) => {
$.ajax({
url: protocol + '//' + window.CONFIG.SERVICE_URL + '接口地址',
type: 'post',
data: sendData,
//ajax2.0可以不用设置请求头,但是jq帮我们自动设置了,这样的话需要我们自己取消掉
contentType:false,
//取消帮我们格式化数据,是什么就是什么
processData:false,
success: function (res) {
if (typeof res === 'string') {
res = JSON.parse(res)
}
if (res.code === 1) {
resolve(res.data[0])
} else {
reject(res)
vue.$message.error(res.message);
}
},
error: function (err) {
console.log(err, 'errrr')
vue.$message.error(err.message);
}
})
})
}
// 格式化数据大小
export var formatDataSize = function(size) {
const format = (num) => {
if (num / parseInt(num) === 1) {
return num;
} else {
const decimalLength = num.toString().split('.')[1].length;
return num.toFixed(decimalLength > 3 ? 3 : decimalLength);
}
};
if (size / 1024 / 1024 < 1) {
return format(size / 1024) + 'KB';
} else {
return format(size / 1024 / 1024) + 'MB';
}
};
// 上传
const {url, name} = await UploadOSS(file, {
maxSize: _maxSize,
overMaxSizeMsg: item.overMaxSizeMsg,
filetype: options.filetype,
});
export default {
uploadImg,
UploadOSS,
vaildFileSize
}
------------------------------------------------------分割线---------------------------------------------------------------
不封装简易版OSS图片上传
<el-form-item label="标签辅助icon:" prop="icon">
<el-upload
accept=".jpg,.jpeg,.png,.JPG,.JPEG,.PNG"
class="ermUp"
action="#"
:http-request="upLoaderFun"
:show-file-list="false"
>
<img v-if="addOrEditruleForm.icon" :src="addOrEditruleForm.icon" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon" />
</el-upload>
<div class="uploaderBtn_box">
<p>请上传像素尺寸为60*60,格式为PNG的图片</p>
</div>
</el-form-item>
// 上传icon
upLoaderFun(data) {
this.$common.ossClient(data.file, 1).then(r => {
if (r.res && r.res.statusCode === 200) {
this.addOrEditruleForm.icon = r.res.requestUrls[0].split('?')[0]
} else {
console.log(r.message)
}
})
},
import { ossUpLoad } from '@/api/common.js'
// oss上传
async ossClient(file, size, handout) {
const isLt2M = file.size / 1024 / 1024 < size
let parms = {}
if (isLt2M) {
parms = await ossUpLoad()
}
return new Promise((resolve, reject) => {
if (!isLt2M) {
Notification.error({
title: '出现错误',
message: `发送数据大小不能超过${size}M!`,
position: 'bottom-right'
})
resolve('error')
}
let filename = ''
if (file.name) {
filename = +new Date() + '/' + file.name
} else {
filename = 'xc-uploadfile/file_' + new Date().getTime() + '.' + 'mp3'
}
const client = new OSS({
accessKeyId: parms.data.AccessKeyId,
accessKeySecret: parms.data.AccessKeySecret,
stsToken: parms.data.SecurityToken,
secure: true,
endpoint: process.env.VUE_APP_SCENE === 'MASTER' ? 'oss-cn-shanghai.aliyuncs.com' : process.env.VUE_APP_SCENE === 'DEV' ? 'oss-cn-hangzhou.aliyuncs.com' : 'oss-cn-hangzhou.aliyuncs.com',
bucket: process.env.VUE_APP_SCENE === 'MASTER' ? handout !== '课程讲义' ? 'cxt-static-master' : 'cxt-auth-master' : process.env.VUE_APP_SCENE === 'DEV' ? handout !== '课程讲义' ? 'cxt-static-dev' : 'cxt-auth-dev' : handout !== '课程讲义' ? 'cxt-static-dev' : 'cxt-auth-dev'
})
async function putObject() {
try {
const result = await client.put(filename, file)
console.log(result, '上传返回数据')
resolve(result)
} catch (e) {
console.log(e, '报错222')
}
}
putObject()
if (parms.code === 1) {
}
})
},
//mian.js文件挂载公共js
import common from '@/util/common' // 公共方法定义
Vue.prototype.$common = common