Vue开发file选择图片组件(限制图片张数)

2022-02-21  本文已影响0人  努力study代码的小哪吒

需求背景

因为开发中多次遇到选择图片功能,所以独立封装成组件来实现功能,减少代码的编写

代码介绍

图片多选功能,并且设置了最多只可上传多少张,以及选择内容进行回传(父组件用v-model即可(v-model => :value + @input 具体可去看Vue官网)

代码

<template>
  <div class="certificate" :style="{width: certWidth + 'px', height: certHeight + 'px'}">
    <div class="camera_icon" :style="{background: bgColor, '--color': addColor }" >
      <p class="title" v-if="titleShow">首图</p>
    </div>
    <input class="select_input" type="file" @change="inputChangeFn($event)" multiple accept="image/*"/>
    <Errormes ref="Errormes"></Errormes>
  </div>
</template>
<script>
export default {
  props: {
    certWidth: {
      type: Number,
      default: 105
    },
    certHeight: {
      type: Number,
      default: 105
    },
    imgsIndex: {
      type: Number
    },
    inputChangeCb: {
      type: Function,
      default: () => {}
    },
    num: {
      type: Number,
      default: 5
    },
    addColor: {
      type: String,
      default: '#DADADA'
    },
    bgColor: {
      type: String,
      default: '#F1F1F1'
    },
    titleShow: {
      type: Boolean,
      default: false
    }
  },
  data: function () {
    return {
      dataUrl: []
    }
  },
  methods: {
    inputChangeFn (e) {
      // this.inputChangeCb && this.inputChangeCb({
      //   e: e,
      //   index: this.imgsIndex
      // })
      this.imgPreview(e)
      this.$emit('input', this.dataUrl)
    },
    imgPreview (file) {
      console.log(this.dataUrl)
      const _this = this
      const files = Array.from(file.target.files)
      if (_this.dataUrl.length + files.length > this.num) {
        _this.$refs.Errormes.ErrormesFun('最多可上传' + this.num + '张图片,请重新上传!')
        return
      }
      let reader
      if (files) {
        files.forEach(file => {
          reader = new FileReader()
          reader.readAsDataURL(file)
          reader.onload = function (e) {
            _this.dataUrl.push(e.target.result)
          }
        })
      }
    }
  }
}
</script>
<style lang="stylus" scoped>
.certificate
  position relative
  width 100%
  height 100%
  .camera_icon
    width 100%
    height 100%
    border-radius 16px
    position relative
    display flex
    justify-content center
    .title
      padding-top 35%
      font-size 28px
      font-family PingFangSC-Medium, PingFang SC
      font-weight 500
    &:before
      content ''
      position absolute
      left 50%
      top 50%
      width 68px
      height 8px
      border-radius 20%
      background var(--color)
      margin-left -34px
      margin-top -4px
    &:after
      content ''
      position absolute
      left 50%
      top 50%
      width 8px
      height 68px
      border-radius 20%
      background var(--color)
      margin-top -34px
      margin-left -4px
  .select_input
    position absolute
    left 0
    top 0
    width 100%
    height 100%
    overflow hidden
    opacity 0
    z-index 222
</style>

上一篇下一篇

猜你喜欢

热点阅读