基于阿里Ant Design of Vue的上传组件二次封装

目前参与的项目使用的UI库是阿里的Ant Design of Vue
由于项目中多处要用到上传组件,又不想每次照着官网的上传组件复制多次上传、删除、查看图片事件,因为可能需要多次修改,所以自己进行了二次封装,将上传单张(上传头像需求)和多张弄到一起

<template>
  <div>
    <a-upload :action="uploadAction"
      list-type="picture-card"
      :disabled="disabled"
      :headers="headers"
      :file-list="fileList"
      :beforeUpload="beforeUpload"
      :data="{biz:bizPath}"
      :multiple="isMultiple"
      :showUploadList="isMultiple"
      @preview="handlePreview"
      @change="handleChange">
      <img v-if="!isMultiple && picUrl"
        :src="getAvatarView()"
        style="height:104px;max-width:300px" />
      <div v-else-if="(isMultiple && fileList.length < limit && !disabled) || (!isMultiple && !picUrl)">
        <a-icon type="plus" />
        <div class="ant-upload-text">{{text}}</div>
      </div>
    </a-upload>
    <a-modal :visible="previewVisible"
      :footer="null"
      @cancel="previewHandleCancel">
      <img alt="example"
        style="width: 100%"
        :src="previewImage" />
    </a-modal>
  </div>
</template>

<script>
import Vue from 'vue'
import { ACCESS_TOKEN } from "@/store/mutation-types"
// import { getFileAccessHttpUrl } from '@/api/manage'

const getFileAccessHttpUrl = (avatar, subStr) => {
  if (!subStr) subStr = 'http'
  if (avatar && avatar.startsWith(subStr)) {
    return avatar;
  } else {
    if (avatar && avatar.length > 0 && avatar.indexOf('[') == -1) {
      return window._CONFIG['staticDomainURL'] + "/" + avatar;
    }
  }
}

const uidGenerator = () => {
  return '-' + parseInt(Math.random() * 10000 + 1, 10);
}
const getFileName = (path) => {
  if (path.lastIndexOf("\\") >= 0) {
    let reg = new RegExp("\\\\", "g");
    path = path.replace(reg, "/");
  }
  return path.substring(path.lastIndexOf("/") + 1);
}
export default {
  name: 'LImageUpload',
  data() {
    return {
      uploadAction: window._CONFIG['domianURL'] + "/sys/common/upload",
      headers: {},
      fileList: [],
      previewImage: "",
      previewVisible: false,
      picUrl: false
    }
  },
  props: {
    text: {
      type: String,
      default: '上传'
    },
    // 父组件传进来的已有的图片数据
    value: {
      type: [String, Array],
      required: false
    },
    // 后端要求携带的其他参数
    bizPath: {
      type: String,
      required: false,
      default: "temp"
    },
    // 只能查看不可上传和删除时开启该属性
    disabled: {
      type: Boolean,
      required: false,
      default: false
    },
    // 是否多图
    isMultiple: {
      type: Boolean,
      required: false,
      default: false
    },
    // 多图情况下限制图片张数
    limit: {
      type: Number,
      required: false,
      default: 9
    }
  },
  watch: {
    value: {
      handler(val) {
        if (val instanceof Array) {
          this.initFileList(val.join(','))
        } else {
          this.initFileList(val)
        }
      },
      deep: true,
      immediate: true
    }
  },
  created() {
    const token = Vue.ls.get(ACCESS_TOKEN);
    this.headers = { "X-Access-Token": token }
  },
  methods: {
  	// 显示已有图片
    initFileList(paths) {
      console.log('initFileList', paths)
      if (!paths || paths.length == 0) {
        this.fileList = [];
        return;
      }
      this.picUrl = true;
      let fileList = [];
      let arr = paths.split(",")
      for (var a = 0; a < arr.length; a++) {
        let url = getFileAccessHttpUrl(arr[a]);
        fileList.push({
          uid: uidGenerator(),
          name: getFileName(arr[a]),
          status: 'done',
          url: url,
          response: {
            status: "history",
            message: arr[a]
          }
        })
      }
      this.fileList = fileList
      console.log('fileList', this.fileList)
    },
    beforeUpload: function (file) {
      var fileType = file.type;
      if (fileType.indexOf('image') < 0) {
        this.$message.warning('请上传图片');
        return false;
      }
    },
    // 关闭弹框
    previewHandleCancel() {
      this.previewVisible = false;
    },
    // 预览
    handlePreview(file) {
      this.previewImage = file.url || file.preview;
      this.previewVisible = true;
    },
    // 上传
    handleChange(info) {
      console.log('info----handleChange', info)
      this.picUrl = false;
      let fileList = info.fileList
      if (info.file.status === 'done') {
        if (info.file.response.success) {
          this.picUrl = true;
          fileList = fileList.map((file) => {
            if (file.response) {
              file.url = getFileAccessHttpUrl(file.response.message);
            }
            return file;
          });
        }
        //this.$message.success(`${info.file.name} 上传成功!`);
      } else if (info.file.status === 'error') {
        this.$message.error(`${info.file.name} 上传失败.`);
      } else if (info.file.status === 'removed') {
        this.handleDelete(info.file)
      }
      this.fileList = fileList
      if (info.file.status === 'done' || info.file.status === 'removed') {
        this.handlePathChange()
      }
    },
    // 回传父组件
    handlePathChange() {
      let uploadFiles = this.fileList
      let path = ''
      if (!uploadFiles || uploadFiles.length == 0) {
        path = ''
      }
      let arr = [];
      if (!this.isMultiple) {
        arr.push(uploadFiles[uploadFiles.length - 1].response.message)
      } else {
        for (var a = 0; a < uploadFiles.length; a++) {
          arr.push(uploadFiles[a].response.message)
        }
      }
      if (arr.length > 0) {
        path = arr.join(",")
      }
      this.$emit('change', path);
    },
    // 删除
    handleDelete(file) {

    },
    // 单图上传显示最新的一张
    getAvatarView() {
      if (this.fileList.length > 0) {
        let url = this.fileList[this.fileList.length - 1].url
        return getFileAccessHttpUrl(url)
      }
    },
  },
  model: {
    prop: 'value',
    event: 'change'
  }
}
</script>

项目和后端交互,图片的地址不是完整的线上路径,需要通过getFileAccessHttpUrl 返还一个完整的线上路径,如果你的项目返回的是一个完整的线上图片路径,可以自己把上面代码稍作修改使用

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Ant Design of Vue 是一个基于 Vue.js 的 UI 组件库,它提供了丰富的组件和样式,可以帮助开发者快速构建美观、易用的 Web 应用程序。其中,Ant Design of Vue 表单封装是一个非常实用的功能,它可以帮助开发者快速构建表单,包括表单验证、表单布局、表单提交等功能,大大提高了开发效率。同时,Ant Design of Vue 表单封装还支持自定义表单组件,开发者可以根据自己的需求定制表单组件,满足不同的业务需求。总之,Ant Design of Vue 表单封装是一个非常实用的功能,可以帮助开发者快速构建高质量的 Web 应用程序。 ### 回答2: Ant Design of Vue是一个基于Vue.js的UI组件库,它提供了一系列优雅且易用的组件,包含有丰富的UI组件、样式和交互行为,可以帮助我们快速构建漂亮而且功能强大的Web应用。 其中,表单是Ant Design of Vue中最核心、最常用的组件之一,因为表单是我们在前端开发中最常用的交互方式。Ant Design of Vue中针对表单封装的功能也非常丰富,主要包括以下几个方面: 1. 表单控件:Ant Design of Vue提供了一系列的表单控件,包括输入框、选择器、日期选择器、开关、单选框、复选框等,这些表单控件都有丰富的属性和事件可以自由控制,可以满足我们在不同的场景下的需求。 2. 表单校验:Ant Design of Vue提供了非常强大的表单校验功能,可以对表单进行必填、数据格式、长度等多个方面的校验,还可以自定义校验规则,方便我们在项目中灵活运用。 3. 表单布局:Ant Design of Vue提供了多种表单布局,包括水平布局、垂直布局、行内布局等,可以根据不同的需求选择不同的布局方式,在表单的美观性、可读性等方面都有很好的表现。 4. 表单数据处理:Ant Design of Vue提供了非常便捷的表单数据处理方式,可以将表单中的数据进行组装、序列化、反序列化等操作,快捷方便。 总之,Ant Design of Vue提供的表单封装功能非常丰富、易用,在我们的前端开发中应用广泛,可以大大提高我们的开发效率、代码质量和用户体验。 ### 回答3: Ant Design of Vue 是一个企业级 UI 设计语言和 Vue.js 的实现版本,其中包括了许多常用的组件,如表格、表单、对话框等。 在 Ant Design of Vue 中,表单是一个非常常用和重要的组件,用于网站的交互和数据处理。Ant Design of Vue 中的表单组件可以通过简单的代码来实现各种表单元素的布局、样式、校验和提交等功能,同时具有良好的用户体验和可维护性。 Ant Design of Vue 的表单封装主要包括三个部分:表单组件、表单项组件和校验规则。 表单组件Ant Design of Vue 中的一个顶层组件,用于包装整个表单。通过定义 props 来配置表单的属性和事件,例如表单的布局方式、表单项组件的数据和样式绑定、表单的提交和重置等。 表单项组件是表单中的一个子组件,用于表示一个表单的输入项,如输入框、单选框、复选框和下拉框等。通过定义 props 和 v-model 来绑定表单项和表单数据,并设置相应的属性和事件来实现校验、关联、联动和交互等功能。 校验规则是 Ant Design of Vue 中用于校验表单项数据合法性的组件。通过定义 rules 属性来配置校验规则,例如数据格式、数据类型、数据范围和数据比较等。当表单提交或失焦时,校验规则会自动进行校验,并在校验不通过时提示相应的错误信息。 总体来说,Ant Design of Vue 中的表单封装具有很高的可用性和可扩展性,能够满足各种不同的业务需求,并且对于前端开发人员来说也十分友好和方便。如果您需要构建一个高品质的企业级表单,那么 Ant Design of Vue 的表单封装一定是您的不二之选。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值