vue2 el-upload上传功能

vue2 el-upload上传功能

<template>
  <div class="box-card-div" style="padding-top: 0">
    <el-card class="box-card box-card-div-el-card wow fadeInLeft">
      <template #header>
        <div class="clearfix">
          <span>发布内容公告</span>
        </div>
      </template>
      <div class="components-container">
        <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
          <el-form-item label="标题" prop="title">
            <el-input v-model="ruleForm.title"></el-input>
          </el-form-item>
          <el-form-item label="发布者" prop="publisher">
            <el-input v-model="ruleForm.publisher"></el-input>
          </el-form-item>
          <el-form-item label="图片" prop="image">
            <el-upload
              class="upload-demo"
              ref="upload"
              :file-list="fileList"
              :http-request="uploadFunc"
              :before-upload="beforeUpload"
              :on-remove="removeFile"
            >
              <el-button size="small" type="primary">选取文件</el-button>
              <template #tip>
                <div class="el-upload__tip">只能上传jpg/png文件,仅能上传一张,且不超过2M</div>
              </template>
            </el-upload>
          </el-form-item>
          <el-form-item label="内容类型" v-if="ruleForm.system === 'activity'">
            <el-select v-model="ruleForm.contentType" placeholder="请选择文章类型">
              <el-option value="1" label="活动">活动</el-option>
              <el-option value="2" label="培训">培训</el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="是否轮播">
            <el-switch
              v-model="ruleForm.isCarousel">
            </el-switch>
          </el-form-item>

          <el-form-item label="标签">
            <el-select v-model="ruleForm.tags" multiple placeholder="请选择标签" style="width: 100%">
              <el-option
                v-for="item in tagsOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>

          <el-form-item label="PDF文件">
            <el-upload
              class="upload-demo"
              ref="upload-pdf"
              :on-remove="handlePdfRemove"
              :file-list="pdfFileList"
              :http-request="uploadPdfFunc"
            >
              <el-button size="small" type="primary">选取文件</el-button>
              <template #top>
                <div class="el-upload__tip">只能上传pdf文件</div>
              </template>
            </el-upload>
          </el-form-item>

          <el-form-item label="内容" prop="content">
            <tinymce-editor
              ref="editor"
              v-model:value="ruleForm.content"
              :disabled="disabled"
            />
          </el-form-item>

          <div style="text-align: center; margin-top: 20px">
            <el-button type="primary" @click="submitForm('ruleForm', true)">发布</el-button>
            <el-button type="primary" @click="submitForm('ruleForm', false)">保存草稿</el-button>
          </div>
        </el-form>
      </div>
    </el-card>
  </div>
</template>

<script>

import TinymceEditor from '@/components/editor/TinymceEditor';

import { createContent } from '@/api/cms';
import { uploadFile } from '@/api/files';
export default {
  name: 'Create',
  components: { TinymceEditor },
  data () {
    return {
      domainName: '',
      uploading: false,
      content: '',
      ruleForm: {
        title: '',
        publisher: '',
        content: '',
        contentType: '0',
        system: '',
        type: '',
        image: '',
        pdfFiles: [],
        isFormal: '',
        isCarousel: false,
        tags: []
      },
      rules: {
        title: [
          { required: true, message: '请输入标题', trigger: 'blur' }
        ],
        publisher: [
          { required: true, message: '请输入发布者', trigger: 'blur' }
        ],
        content: [
          { required: true, message: '请输入内容', trigger: 'blur' }
        ]
      },
      fileList: [],
      pdfFileList: [],
      disabled: false,
      tagsOptions: [{
        value: 'mustRead',
        label: '必读'
      }]
    }
  },
  created () {
    this.ruleForm.system = this.$route.query.system
    this.ruleForm.type = this.$route.query.type
    if (this.ruleForm.system === 'activity') {
      this.ruleForm.contentType = '1'
    }
    this.domainName = window.location.origin
  },
  methods: {
    uploadFunc (info) {
      this.uploading = true;
      const { file } = info;
      const formData = new FormData();
      formData.append('file', file);
      uploadFile(formData).then(res => {
        this.fileList.push({
          key: res.fileId,
          url: res.url,
          name: file.name,
        });
        this.ruleForm.image = res.url;
        this.uploading = false;
      }, (err) => {
        this.uploading = false;
        this.$message({
          type: 'error',
          message: `图片 ${file.name} 上传失败:${err.errmsg}`,
        })
        console.error(err);
      });
    },
    beforeUpload () {
      if (this.fileList.length > 0 || this.uploading) {
        this.$message({
          type: 'error',
          message: '图片仅允许上传1张',
        });
      }
    },
    removeFile () {
      this.fileList = [];
    },
    submitForm (formName, isFormal) {
      this.ruleForm.isFormal = isFormal
      this.ruleForm.pdfFiles = this.pdfFileList;
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.ruleForm.contentType = parseInt(this.ruleForm.contentType)
          createContent(this.ruleForm).then(() => {
            if (isFormal === true) {
              this.$router.push({ path: '/system/article' })
            } else {
              this.$router.push({ path: '/system/draft-box' })
            }
          })
        }
      })
    },
    uploadPdfFunc (info) {
      const { file } = info;
      const formData = new FormData();
      formData.append('file', file);
      uploadFile(formData).then((res) => {
        this.pdfFileList.push({
          key: res.fileId,
          url: res.url,
          name: file.name,
        });
      }, (err) => {
        this.$message({
          type: 'error',
          message: `PDF ${file.name} 上传失败:${err.errmsg}`,
        })
        console.error(err);
      });
    },
    handlePdfRemove (file) {
      const index = this.pdfFileList.findIndex(pdf => pdf.url === file.url);
      this.pdfFileList.splice(index, 1);
    },
  }
}
</script>

<style scoped>
  .box-card-div {
    padding-left: 20px;
    padding-right: 20px;
    padding-bottom: 20px;
  }
</style>

     <div style="display: flex;align-items: center;">
        <el-upload
           class="avatar-uploader upload_file"
           :auto-upload="false"
           :show-file-list="false"
           action=""
           :on-change="handleImport"
         >
           <el-button type="primary">选择文件</el-button>
         </el-upload>
         <span style="font-size: 12px;">支持批量上传,上传格式为excel文件</span>
       </div>


	const handleImport = (file) => {
	  if (file.name.split('.')[1] !== 'xlsx' ||
	   file.raw.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
	      ElMessage({
	        type: 'error',
	        message: '上传文件后缀只能是.xlsx的EXCEL格式文档',
	      });
	      return
	  }
	  const formData = new FormData();
	  formData.append('file', file.raw);
	  // 接口逻辑
	  if (activeTab.value == 2) {
	      importFloor(formData).then(res => {
	        if(res.error_no == 0) {
	          ElMessage.success({
	            message: '上传成功'
	          })
	          showImportDialog.value = false
	          getFloorInfo()
	          // fileList.value.push({id: Math.random(),
	           fileName: file.name.split('.')[0], size: Math.floor(file.raw.size / 1024), status: true})
	        } else if (res.error_no == 4001) {
	          isShowFail.value = true
	          failList.value = res.data.details
	          failUrl.value = res.data.download_fail_url
	          numData.value.total = res.data.total
	          numData.value.success_num = res.data.success_num
	          numData.value.fail_num = res.data.fail_num
	        }
	      })
	  } else if (activeTab.value == 3) {
	    importUnit(formData).then(res => {
	        if(res.error_no == 0) {
	          ElMessage.success({
	            message: '上传成功'
	          })
	          showImportDialog.value = false
	          getUnitInfo()
	          // fileList.value.push({id: Math.random(), fileName: file.name.split('.')[0], size: Math.floor(file.raw.size / 1024), status: true})
	        } else if (res.error_no == 4001) {
	          isShowFail.value = true
	          failList.value = res.data.details
	          failUrl.value = res.data.download_fail_url
	          numData.value.total = res.data.total
	          numData.value.success_num = res.data.success_num
	          numData.value.fail_num = res.data.fail_num
	        }
	      })
	  }
	}
<think>嗯,用户想在Vue3中使用element-ui的el-upload组件来限制上传文件的格式。不过根据提供的引用内容,用户可能实际上是在用Element-Plus,因为Element-UI主要是针对Vue2的,而Element-Plus是Vue3版本的。我需要先确认这一点,但根据引用里的代码示例,确实提到了Vue3和Element-Plus的el-upload组件。所以用户可能混淆了element-ui和element-plus的名称,但实际应该使用Element-Plus。 接下来,用户的需求是限制上传文件格式。根据引用中的信息,可以通过设置accept属性来指定文件类型,比如accept=".jpg,.png"。不过,引用[2]提到,虽然设置accept可以限制选择文件的类型,但用户仍然可能通过修改文件选择框的选项来上传其他类型,所以在before-upload钩子中进行进一步的验证是必要的。 因此,我需要提供一个示例代码,展示如何在el-upload中同时使用accept属性和before-upload方法来实现双重验证。同时,用户可能还需要处理上传成功后的回调,以及样式调整。 另外,引用[2]中提到http-request可以覆盖默认的上传行为,但用户的问题可能不需要自定义上传,只需要基本的限制格式。不过,如果用户需要自定义上传逻辑,可能需要使用http-request,但根据问题描述,用户可能只需要前端验证。 还需要注意,在Vue3中,使用Element-Plus的话,组件的导入方式是否正确,以及是否使用了正确的语法,比如组合式API。不过示例代码中使用的是选项式API,可能用户更熟悉这种方式。 总结步骤应该是: 1.el-upload组件中添加accept属性,指定允许的文件类型,比如accept=".jpg,.png,.pdf"。 2. 在before-upload方法中检查文件类型,如果不符合,则提示用户并返回false阻止上传。 3. 可能需要处理上传成功后的回调函数,比如更新文件列表或提示成功信息。 4. 注意在限制为只能上传一个文件时,结合limit属性,并在before-upload中检查已有文件数量,如引用[1]中的示例。 现在需要将这些步骤整合成一个Vue3的示例代码,同时确保语法正确,比如使用setup语法或者选项式API。根据用户提供的引用代码,他们可能更倾向于选项式API,所以示例代码可以采用类似结构。 另外,可能需要处理用户上传时的错误提示,比如使用ElMessage来显示警告信息,这需要从Element-Plus中正确导入ElMessage组件。 最后,确保代码中的action属性设置正确,如果用户需要自定义上传,可能需要覆盖http-request,但根据问题描述,可能不需要,所以保持action为某个URL,或者设置为“#”如果暂时不需要后端处理。 检查是否有遗漏的点,比如文件大小限制,但用户的问题仅涉及格式限制,所以可以暂时不考虑。但如果有必要,可以在before-upload中添加文件大小的检查。 现在,编写示例代码,并解释每个部分的作用,确保用户能够理解如何实现文件格式的限制。同时,需要引用提供的引用内容中的相关部分,如引用[1]中的limit属性和before-upload检查,引用[2]中的accept和before-upload验证。</think>在 Vue3 中使用 Element-Plus 的 `el-upload` 组件限制文件格式,可通过以下两种方式实现: ### 实现方案 ```vue <template> <el-upload class="upload-demo" :action="uploadUrl" :limit="1" :accept="allowedTypes" // 设置可接受的文件类型 :before-upload="validateFileType" // 上传前校验 :file-list="fileList" > <el-button type="primary">点击上传(仅支持JPG/PNG/PDF)</el-button> </el-upload> </template> <script> import { ElMessage } from 'element-plus'; export default { data() { return { uploadUrl: '#', // 实际需替换为上传接口地址 allowedTypes: '.jpg,.jpeg,.png,.pdf', // 允许的文件后缀 fileList: [] // 已上传文件列表 }; }, methods: { validateFileType(file) { const allowed = ['image/jpeg', 'image/png', 'application/pdf']; if (!allowed.includes(file.type)) { ElMessage.warning('仅支持 JPG/PNG/PDF 格式'); return false; // 阻止上传[^2] } return true; } } }; </script> ``` ### 关键配置说明 1. **accept 属性** 通过 MIME 类型或文件后缀限制选择器显示的文件类型(如 `.jpg,.pdf`),但需注意: - 浏览器仅过滤选择器显示的文件类型,无法阻止手动修改文件后缀 - 需要与后端文件头校验配合才能完全限制[^2] 2. **before-upload 钩子** 通过校验 `file.type` 属性实现二次验证(需注意不同浏览器返回的 MIME 类型可能不一致) 3. **文件类型对照表** | 文件类型 | MIME 类型 | 常见后缀 | |----------|--------------------------|--------------| | 图片 | image/jpeg, image/png | .jpg, .png | | PDF | application/pdf | .pdf | ### 相关问题 1. 如何同时限制文件格式和文件大小? 2. 为什么有些 PDF 文件无法通过校验? 3. 如何实现自定义上传接口的鉴权?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值