PictureSelect コンポーネント パッケージ: 画像を選択して検証する機能を実現します。

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>

 

おすすめ

転載: blog.csdn.net/sleepwalker_1992/article/details/127076267