[前端工程化 - 组件封装]图片上传组件

前言

大家好,我是辉夜真是太可爱啦,这是我即将最新开启的组件封装或基于组件库二次封装系列,代码均以 vue2 为例,组件库以 vant 为栗子

组件的封装在工作中使用的用处还是很大的,主要体现在维护的方便,可以将所有固定的代码抽到同一个组件中进行统一管理。

封装目的

这次是实现的是图片上传的功能,由于 vant 组件的 uploader 组件的 v-model 设计不太合理。

一般来说,正常单张图片的值是一个 String ,例如 https://xxxx.jpg

然后一串图片是一个 Array ,例如 ['https://xxxx.jpg' , 'https://xxxx.jpg']

然后我们仅通过一个 v-model 即可绑定这个值,无需对图片上传之后值的更新,图片删除之后值的清空,或者是默认值的渲染再做多余的管理,可以大大的提升图片相关功能的开发效率。

后期还可以配合写一个 form 组件,使用 json 生成 form 表单。

Props

  • v-model 绑定的图片的值
  • max-count 绑定的最大值,1为单张图,大于1为列表
  • tips 文件上传提示语

Slot

  • defautl 默认插槽,用于修改图片上传的控件

开始封装

先书写 template 板块,关于插槽内的图片上传框的样式请自行修改。

html 复制代码
<template>
  <div class="image-uploader-component-main-box">
    <van-uploader
      :after-read="afterRead"
      :max-size="1024 * 1024 * 10"
      @delete="deleteFile"
      v-model="fileList"
      :max-count="maxCount"
      accept="image/png,image/jpeg,image/jpg"
    >
      <slot>
        <div class="upload-box">
          <span>图片上传</span>
        </div>
      </slot>
    </van-uploader>
  </div>
</template>

接下来,就是封装 js 的部分,由于fileList的格式是固定的,所以接下来需要用一个currentValue来进行绑定,fileList的数组,在初次渲染的时候,需要将currentValue中的值赋值给fileList,这样子才能保持两边数组的同步。

当然,uploadImage 图片上传的调用行为,请自行修改。

javascript 复制代码
<script>
export default {
  name: 'ImageUploader',

  props: {
    value: {
      type: [Array, String],
      default: '',
    },
    maxCount: {
      type: Number,
      default: 1,
    },
  },

  data() {
    return {
      currentValue: this.value,
      fileList: [],
      isInit: false, // 将一开始的默认值赋值给 fileList
    }
  },

  watch: {
    value: {
      handler(newValue) {
        if (!this.isInit) {
          if (this.maxCount === 1) {
            this.fileList = [
              {
                url: newValue,
                status: 'success',
                message: '上传成功',
              },
            ]
          } else {
            newValue.forEach((item) => {
              this.fileList.push({
                url: item,
                status: 'success',
                message: '上传成功',
              })
            })
          }
        }
        this.currentValue = newValue
      },
    },
  },

  methods: {
    afterRead(file) {
      this.isInit = true
      file.status = 'uploading'
      file.message = '上传中...'
      const formData = new FormData()
      formData.append('file', file.file)
      uploadImage(formData)
        .then((res) => {
          if (res.url) {
            file.status = 'success'
            file.message = '上传成功'
            file.url = res // FIXME: 这里上传不做全地址处理了
            if (this.maxCount === 1) {
              this.currentValue = res.url
            } else {
              this.currentValue.push(res.url)
            }
            this.$emit('input', this.currentValue)
          } else {
            file.status = 'failed'
            file.message = '上传失败'
            this.$toast.fail(res.error)
          }
        })
        .catch(() => {
          file.status = 'failed'
          file.message = '上传失败'
        })
    },

    deleteFile(file) {
      if (this.maxCount === 1) {
        this.currentValue = ''
      } else {
        this.currentValue.splice(
          this.currentValue.findIndex((x) => x === file.url),
          1
        )
      }
      this.$emit('input', this.currentValue)
    },
  },
}
</script>

至于另外别的 API,此处不再做多余的赘述,仅仅搬运下即可。

组件使用

  • 单个使用
javascript 复制代码
<ImageUploader v-model="imgUrl"></ImageUploader>

data() {
  return {
    imgUrl: ''
  }
},
  • 多个使用
ruby 复制代码
<ImageUploader v-model="imgList" :max-count="5"></ImageUploader>

data() {
  return {
    imgList: []
  }
},
相关推荐
sunbyte2 小时前
Tailwind CSS 初学者入门指南:项目集成,主要变更内容!
前端·css
可爱的秋秋啊2 小时前
vue3,element ui框架中为el-table表格实现自动滚动,并实现表头汇总数据
前端·vue.js·笔记·elementui
一夜枫林2 小时前
uniapp自定义拖拽排列
前端·javascript·uni-app
IT瘾君4 小时前
JavaWeb:Html&Css
前端·html
264玫瑰资源库5 小时前
问道数码兽 怀旧剧情回合手游源码搭建教程(反查重优化版)
java·开发语言·前端·游戏
喝拿铁写前端5 小时前
从圣经Babel到现代编译器:没开玩笑,普通程序员也能写出自己的编译器!
前端·架构·前端框架
HED5 小时前
VUE项目发版后用户访问的仍然是旧页面?原因和解决方案都在这啦!
前端·vue.js
拉不动的猪5 小时前
前端自做埋点,我们应该要注意的几个问题
前端·javascript·面试
王景程5 小时前
如何测试短信接口
java·服务器·前端
安冬的码畜日常6 小时前
【AI 加持下的 Python 编程实战 2_10】DIY 拓展:从扫雷小游戏开发再探问题分解与 AI 代码调试能力(中)
开发语言·前端·人工智能·ai·扫雷游戏·ai辅助编程·辅助编程