Skip to content

上传组件

上传组件提供了文件上传功能,支持图片、文档、视频、音频等多种文件类型的上传。组件提供了丰富的配置选项,支持多文件上传、文件预览、上传进度监控等功能,有助于实现灵活的文件管理场景。

基础使用

设置上传成功回调

在上传组件的 onSuccess 回调中,必须将上传成功后的 URL 赋值给 file.url,否则表单将无法获取文件数据:

js
function onSuccess($inject) {
   const res = $inject.args[0];
   const file = $inject.args[1];
   // 将上传后的URL赋值给file.url
    file.url = res.data.url;
}

这样可以确保表单提交时能够正确获取上传的文件信息。

设置请求头

文件上传时将触发表单的 beforeFetch 事件,可在该事件回调中修改请求头(headers)配置,例如添加认证token:

js
function beforeFetch(config, data) {
    // 从外部数据获取全局 token
    const token = data.api.getData('globalToken');
    if (!config.headers) {
        config.headers = {};
    }
    config.headers.token = token;
}

保存更多数据

如果期望上传组件的 value 类型为 object[],需要将上传的结果数据赋值给 file.value

js
function onSuccess($inject) {
   const res = $inject.args[0];
   const file = $inject.args[1];
    file.url = res.data.url;
    file.name = res.data.name;
    file.value = res.data;  // 保存完整的返回数据
}

全局配置

在实际项目中,通常需要为所有上传组件设置统一的上传地址、成功回调和请求头。FormCreate 提供了三种方式来设置全局配置,按执行顺序依次为:

  1. formCreate.parser(全局替换配置)- 直接修改规则本身,执行时机最早
  2. option.global(普通配置)- 只在规则中没有对应属性时生效
  3. option.global.deep(深度合并配置)- 强制覆盖规则中的同名属性

执行顺序

执行顺序:Parser → option.global(普通配置) → option.global.deep(深度合并)

详细说明请查看:设置组件默认配置

方式一:使用 Parser 全局替换(推荐用于强制统一)

通过 formCreate.parser 注册解析器,直接修改规则本身。适合需要强制统一所有上传组件配置的场景。

main.js 中注册 Parser

js
// main.js
import formCreate from '@form-create/element-ui';

formCreate.parser({
  name: 'upload',
  merge: true,
  init({rule}) {
    // 直接修改规则本身
    rule.props.action = '/api/upload';
    rule.props.onSuccess = function (res, file) {
      // 必须设置 file.url,否则表单无法获取文件数据
      file.url = res.data.url;
      file.name = res.data.name;
    };
    rule.props.onError = function (err) {
      console.error('上传失败:', err);
    };
  }
});

在组件中使用

vue
<template>
  <form-create :rule="rule" v-model:api="fApi" :option="options"/>
</template>

<script>
export default {
  data() {
    return {
      fApi: {},
      options: {
        // 表单级别的 beforeFetch 事件,用于设置请求头
        beforeFetch: function (config, data) {
          // 从外部数据获取全局 token
          const token = data.api.getData('globalToken');
          if (!config.headers) {
            config.headers = {};
          }
          config.headers.Authorization = 'Bearer ' + token;
          return config;
        }
      },
      rule: [
        {
          type: 'upload',
          field: 'upload1',
          title: '上传图片',
          props: {
            listType: 'picture-card'
            // action 和 onSuccess 会被 Parser 自动设置
          }
        },
        {
          type: 'upload',
          field: 'upload2',
          title: '上传文件',
          props: {
            action: '/custom-upload',  // 这个会被 Parser 覆盖为 '/api/upload'
            onSuccess: function (res, file) {
              console.log('自定义处理');  // 这个会被 Parser 覆盖
            }
          }
        }
      ]
    }
  }
}
</script>

方式二:使用 option.global 普通配置

使用 option.global 设置全局配置,只在规则中没有定义对应属性时才会生效。

vue
<template>
  <form-create :rule="rule" v-model:api="fApi" :option="options"/>
</template>

<script>
export default {
  data() {
    return {
      fApi: {},
      options: {
        // 表单级别的 beforeFetch 事件
        beforeFetch: function (config, data) {
          const token = data.api.getData('globalToken');
          if (!config.headers) {
            config.headers = {};
          }
          config.headers.Authorization = 'Bearer ' + token;
          return config;
        },
        global: {
          upload: {
            props: {
              // 只在规则中没有定义 action 时才会生效
              action: '/api/upload',
              // 只在规则中没有定义 onSuccess 时才会生效
              onSuccess: function (res, file) {
                file.url = res.data.url;
                file.name = res.data.name;
              },
              onError: function (err) {
                console.error('上传失败:', err);
              }
            }
          }
        }
      },
      rule: [
        {
          type: 'upload',
          field: 'upload1',
          title: '上传图片',
          props: {
            listType: 'picture-card'
            // 没有定义 action 和 onSuccess,会使用全局配置
          }
        },
        {
          type: 'upload',
          field: 'upload2',
          title: '上传文件',
          props: {
            action: '/custom-upload',  // 规则中定义了 action,全局配置不会生效
            onSuccess: function (res, file) {
              console.log('自定义处理');  // 规则中定义了 onSuccess,全局配置不会生效
            }
          }
        }
      ]
    }
  }
}
</script>

方式三:使用 option.global.deep 强制覆盖

使用 deep 属性,通过点号路径指定要强制覆盖的属性,会强制覆盖规则中的同名属性。

vue
<template>
  <form-create :rule="rule" v-model:api="fApi" :option="options"/>
</template>

<script>
export default {
  data() {
    return {
      fApi: {},
      options: {
        // 表单级别的 beforeFetch 事件
        beforeFetch: function (config, data) {
          const token = data.api.getData('globalToken');
          if (!config.headers) {
            config.headers = {};
          }
          config.headers.Authorization = 'Bearer ' + token;
          return config;
        },
        global: {
          upload: {
            // 深度合并配置:使用点号路径指定要覆盖的属性
            deep: {
              'props.action': '/api/upload',  // 强制覆盖规则中的 action
              'props.onSuccess': function (res, file) {
                // 强制覆盖规则中的 onSuccess
                file.url = res.data.url;
                file.name = res.data.name;
              },
              'props.onError': function (err) {
                console.error('统一的上传失败处理:', err);
              }
            }
          }
        }
      },
      rule: [
        {
          type: 'upload',
          field: 'upload1',
          title: '上传图片',
          props: {
            action: '/old-upload',  // 这个会被全局配置覆盖为 '/api/upload'
            onSuccess: function (res, file) {
              console.log('自定义处理');  // 这个会被全局配置覆盖
            }
          }
        },
        {
          type: 'upload',
          field: 'upload2',
          title: '上传文件',
          props: {
            // 没有定义 action 和 onSuccess,会使用全局配置
          }
        }
      ]
    }
  }
}
</script>

设置全局 beforeFetch 事件

beforeFetch 是表单级别的事件,需要在 option 中配置,而不是在组件的 props 中。该事件会在所有上传请求之前触发,适合统一设置请求头、修改请求参数等。

vue
<template>
  <form-create :rule="rule" v-model:api="fApi" :option="options"/>
</template>

<script>
export default {
  data() {
    return {
      fApi: {},
      options: {
        // 全局 beforeFetch 事件,所有上传请求都会触发
        beforeFetch: function (config, data) {
          // 从外部数据获取全局 token
          const token = data.api.getData('globalToken') || 
                       data.api.getData('$cookie.token') || 
                       '';

                       // 设置请求头
          if (!config.headers) {
            config.headers = {};
          }
          config.headers.Authorization = 'Bearer ' + token;
          config.headers['X-Requested-With'] = 'XMLHttpRequest';

          // 可以修改上传地址
          // config.url = '/api/custom-upload';

          // 可以添加额外的请求参数
          // config.data = {
          //   ...config.data,
          //   category: 'image'
          // };

          return config;
        }
      },
      rule: [
        {
          type: 'upload',
          field: 'upload1',
          title: '上传图片',
          props: {
            action: '/api/upload'
            // beforeFetch 会在上传前自动触发
          }
        }
      ]
    }
  },
  mounted() {
    // 设置全局 token,供 beforeFetch 使用
    this.$formCreate.setData({
      globalToken: 'your-token-here'
    });
  }
}
</script>

使用建议

  • Parser 配置:适用于需要强制统一所有上传组件配置的场景,执行时机最早,会覆盖规则中的配置
  • 普通配置(option.global):适用于需要为未配置的上传组件提供默认值的场景,不会覆盖规则中已存在的配置
  • 深度合并配置(option.global.deep):适用于需要强制覆盖规则中配置的场景,即使规则中已经定义了对应属性
  • beforeFetch 事件:适用于需要统一设置请求头、修改请求参数等场景,在表单级别配置即可

配置项

上传组件提供了丰富的配置选项,您可以通过在设计器中配置属性来自定义上传组件的行为。

属性名类型默认值必需说明
disabledBoolean-是否禁用
listTypeStringpicture-card文件列表类型(text/picture/picture-card)
multipleBoolean-是否支持多文件上传
nameString-上传的文件字段名
acceptString-接受上传的文件类型
actionString/上传的地址
beforeUploadFunction-上传文件之前的钩子
beforeRemoveFunction-删除文件之前的钩子
onSuccessFunction-文件上传成功时的钩子
headersObject-设置上传请求头
dataObject-上传时附带的额外参数
withCredentialsBoolean-支持发送 cookie 凭证信息
autoUploadBooleantrue是否自动上传
limitNumber-最大允许上传个数

重要说明:

  • listType:设置上传文件列表的展示方式,picture-card 适用于图片上传
  • onSuccess:必须在此回调中设置 file.url,否则表单无法获取文件数据
  • accept:可以设置为文件类型(如 image/*.pdf 等)来限制上传文件类型
  • action:上传接口地址,可以是完整的 URL 或相对路径

事件

上传组件提供了丰富的事件,方便您监听上传状态变化并执行相应的处理。

事件名参数说明
changefile, fileList文件状态改变时的钩子
removefile, fileList文件列表移除文件时的钩子
previewfile点击文件列表中已上传的文件时的钩子
errorerror, file, fileList上传失败时的钩子
progressevent, file, fileList上传进度时的钩子
exceedfiles, fileList文件超出个数限制时的钩子

方法

上传组件内部提供了多种方法,用于处理文件上传的各种操作。

方法名参数说明返回值
clearFiles-清空已上传的文件列表-
abortfile取消上传-
submit-手动上传文件列表-

方法使用示例

清空文件列表

js
function clearUpload($inject) {
    const uploadInstance = $inject.api.el('ref_F2vulxvqc841dac');
    uploadInstance.clearFiles();
}

注意事项

  1. 必须设置 file.url:在 onSuccess 回调中必须设置 file.url = res.data.url,否则表单提交时无法获取文件信息。

  2. beforeFetch 事件:如果需要添加上传请求头(如认证 token),应该在表单的 beforeFetch 事件中设置,而不是在组件的 headers 属性中设置。

  3. 不同 UI 框架的配置差异:element-plus 和 ant-design-vue 在上传组件的配置上存在差异,请根据使用的 UI 框架查看对应文档: