1、组件封装
<template>
<div class="picture-select">
<div class="img-content" :style="contentStyle" @click="imgSelect">
<img v-if="value && value.length > 0" :src="value" :style="imgStyle" alt="图片错误"/>
<i v-else class="el-icon-plus plus-icon"></i>
</div>
<input ref="imgUploadInput"
type="file"
:accept="acceptType"
class="img-input"
@change="imgSelectChange"/>
<el-button type="success" size="small" @click="imgSelect">选择图片</el-button>
</div>
</template>
<script>
export default {
name: 'picture-select',
props: {
// base64格式的图片数据
value: {},
// 可上传的图片类型
acceptType: {
type: String,
default() {
return '.jpg,.jpeg,.png';
}
},
// 可上传的最大图片大小
maxSize: {
type: Number,
default() {
return 2 * 1024 * 1024;
}
},
// 可上传图片的最大尺寸,[宽度, 高度];[0, 0]表示不限制尺寸
maxWidthHeight: {
type: Array,
default() {
return [0, 0];
}
},
// 图片展示框宽度
width: {
type: Number,
default() {
return 300;
}
},
// 图片展示框高度
height: {
type: Number,
default() {
return 300;
}
},
},
model: {
prop: 'value',
event: 'change',
},
data() {
return {
contentStyle: `width: ${this.width}px; height: ${this.height}px;`,
imgStyle: `max-width: ${this.width}px; max-height: ${this.height}px;`,
}
},
methods: {
// 点击上传图片
imgSelect() {
this.$refs.imgUploadInput.click();
},
// 选择图片后
imgSelectChange() {
const file = this.$refs.imgUploadInput.files[0]; // 获取上传的文件
if (!file) {
return;
}
const type = file.name.split('.').slice(-1)[0].toLowerCase(); // 获取上传的文件类型
if (this.acceptType.indexOf(type) === -1) {
const tip = `所选图片格式不正确,请选择${this.acceptType}格式的图片!`;
this.$alert(tip, '错误', { type: 'error'});
this.$refs.imgUploadInput.value = '';
return;
}
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (e) => {
// 文件读取成功后
// 先校验图片尺寸,再校验图片大小
this.checkWidthHeight(e);
};
},
// 校验图片宽高限制
checkWidthHeight(e) {
let fileData = e.target.result;
let fileSize = e.total;
if (this.maxWidthHeight.length === 2 && this.maxWidthHeight[0] > 0 && this.maxWidthHeight[1] > 0) {
// 限制上传图片尺寸
const img = new Image();
img.src = fileData;
img.onload = (event) => {
const width = event.path[0].width;
const height = event.path[0].height;
if (width > this.maxWidthHeight[0] || height > this.maxWidthHeight[1]) {
const tip = `请上传宽高不大于${this.maxWidthHeight[0]}px*${this.maxWidthHeight[1]}px的图片!`
this.$alert(tip, '错误', { type: 'error'});
this.$refs.imgUploadInput.value = '';
} else {
this.checkSize(fileData, fileSize);
}
}
} else {
this.checkSize(fileData, fileSize);
}
},
// 校验图片大小
checkSize(fileData, fileSize) {
if (this.maxSize > 0 && this.maxSize < fileSize) {
// 上传图片大小超过限制
let size = '';
if (this.maxSize < 1024 * 1024){ // 限制最大文件大小小于1MB
size = `${(this.maxSize / 1024).toFixed(2)}KB`;
} else {
size = `${(this.maxSize / (1024 * 1024)).toFixed(2)}MB`;
}
const tip = `请上传不大于${size}的图片!`
this.$alert(tip, '错误', { type: 'error'});
this.$refs.imgUploadInput.value = '';
} else {
this.$emit('change', fileData);
}
}
}
}
</script>
<style scoped lang="scss">
.picture-select {
display: flex;
align-items: center;
.img-content {
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
margin-right: 10px;
border: 1px solid #c0ccda;
background-color: #fbfdff;
border-radius: 4px;
.plus-icon {
font-size: 40px;
color: #8c939d;
font-weight: 300;
}
}
.img-input{
display: none;
}
}
</style>
2、组件使用
<template>
<div>
<picture-select
v-model="value"
:maxSize="4 * 1024 *1024"
:maxWidthHeight="[1000,1000]"
:width="200"
:height="200"
@change="imgChange"
></picture-select>
</div>
</template>
<script>
import PictureSelect from 'components/PictureSelect/index.vue';
export default {
name: 'example',
components: { PictureSelect },
data() {
return {
value: '',
};
},
mounted() {
},
methods: {
imgChange(val) {
console.log(val);
}
}
};
</script>
<style scoped>
</style>