elementui之封装下载模板和导入文件组件

20 篇文章 1 订阅

elementui之封装下载模板和上传组件

封装代码如下:

<template>
  <div>
    <el-dialog
      :title="exportStatus? '导入结果' : '一键导入数据'"
      :visible.sync="dialogVisible"
      width="905px"
      :before-close="handleClose"
      class="export-standard-speech"
    >
    <div class="standard-export" v-if="!exportStatus">
      <div class="export-title">1、下载导入模板</div>
      <div class="export-warning">根据提示完善表格内容</div>
      <div class="export-download-btn">
        <img
          src="@/assets/img/download-demo-icon.png"
          width="12px"
          style="
            vertical-align: baseline;
            margin-right: 3px;
            margin-top:2px;
            display: inline-block;
          "
        />
        <a
          class="a-line"
          :href="downloadDemoUrl"
          download="项目导入模板.xlsx"
          title="下载空的表格模板"
        >下载空的表格模板</a>
      </div>
      <div class="export-title">2、上传完善后的表格</div>
      <el-upload
        class="upload-demo-xls"
        drag
        ref="speechDemoUpload"
        action=""
        :file-list="fileList"
        :auto-upload="false"
        :show-file-list="false"
        accept=".xls,.xlsx,.csv"
        :on-change="handleChange"
      >
        <div class="el-upload__text" v-if="!uploadStatus">将文件拖到此处,或点击<em>上传</em></div>
        <div class="el-upload__text" v-else>
          <span class="file-name">{{ this.file && this.file.name }}</span>
          <span class="file-size">{{bytesToSize(this.file.size)}}</span>
          <span class="file-select">重新选择</span>
        </div>
      </el-upload>
      <div class="h32 flex-center-center" style="margin-top:38px">
        <Button text="取消" background="#fff" border="#4646E6" color="#4646E6" class="ml10"  @click.native="cancelExport" ></Button>
        <Button text="导入" background="#4646E6" color="#fff" class="ml10"  @click.native="xlsDemoExport" :setGray="isFile"></Button>
      </div>
    </div>
    <div v-if="exportStatus && failNum > 0">
      <div class="fail-num">
        <img src="@/assets/img/export-fail-img.png" alt="" class="mr10">
        导入失败
        <span>{{failNum}}</span>
        数据
      </div>
      <div class="export-fail-table">
        <div class="export-fail-text">以下为导入失败的项目,您可修改后重新导入</div>
        <el-table
          :data="tableData"
          height="220"
        >
          <el-table-column
            prop="lineNum"
            label="Execel行数"
            width="220"
            align="left"
          >
          </el-table-column>
          <el-table-column
            prop="projectCode"
            label="项目编号"
            width="220"
            align="center"
          >
          </el-table-column>
          <el-table-column
            prop="failReason"
            label="失败原因"
            width="220"
            align="right"
          >
          </el-table-column>
        </el-table>
      </div>
      <div class="h32 flex-center-center" style="margin-top:23px">
        <Button text="关闭" background="#fff" border="#4646E6" color="#4646E6"   @click.native="cancelExport" ></Button>
      </div>
    </div>
    <div v-if="exportStatus && failNum == 0">
      <div class="success-img">
        <img src="@/assets/img/export-success-img.png" alt="" class="mr10">
      </div>
      <div class="success-text">
        成功导入
        <span>{{ successNum }}</span>
        数据
      </div>
      <div class="h32 flex-center-center" style="margin-top:23px">
        <Button text="完成" background="#4646E6" color="#fff" class=""  @click.native="cancelExport"></Button>
      </div>
    </div>
    </el-dialog>
  </div>
</template>

<script>
import Button from "@/components/Button";
import { upload, service } from '@/utils/request-brand'
import { bytesToSize } from '@/utils'

export default {
  name: 'ImportData',
  components: {
    Button
  },
  props: {
    showDialogVisible: {
      type: Boolean,
      default: false,
      required: true
    },
    downloadDemoUrl:{
      type: String,
      required: true
    },
    uploadFileUrl:{
      type: String,
      required: true
    },
    // 考虑上传时其他参数的情况
    otherUploadData:{
      type: Object,
      default:() => {
        return {}
      }
    }
  },
  computed: {
    userAccountID() {
      return this.$store.state.user.userAccountID;
    },
    isFile(){
      if(this.file){
        return false
      } else {
        return true
      }
    }
  },
  watch: {
    showDialogVisible(newVal) {
      // console.log(newVal);
      this.dialogVisible = newVal
    }
  },
  data () {
    return {
      dialogVisible: false,
      fileList: [],
      file: null,
      // 上传文件的状态切换
      uploadStatus: false,
      successNum: 0,
      failNum: 0,
      tableData: [],
      // 导入的状态
      exportStatus: false,
    };
  },
  methods: {
    bytesToSize,
    handleClose(done) {
      this.dialogVisible = false
      this.$emit('dialogVisible', false)
    },
    // 取消或者清空上传的文件和数据
    cancelExport(){
      // this.$refs.speechDemoUpload.clearFiles()
      this.fileList = []
      this.file = null
      this.successNum = 0
      this.failNum = 0
      this.tableData = []
      this.uploadStatus = false
      this.exportStatus = false
      this.$emit('dialogVisible', false)
    },
    // 上传的文件改变时(覆盖原来的文件)
    handleChange(file, fileList){
      // console.log(file);
      let extension = file.raw.name.substring(file.raw.name.lastIndexOf(".") + 1);
      let size = file.size / 1024 / 1024;
      // let size = file.size / 1024;
      // console.log(extension, extension.toLowerCase() !== "xlsx");
      if (!['xlsx','xls','csv'].includes(extension.toLowerCase())) {
        this.$message.warning("文件格式不正确,请上传xls / xlsx / csv格式");
        return false;
      }
      if (size > 10) {
        this.$message.warning("文件过大,请进行拆分后分多次上传");
        return false
      }
      // console.log(file.raw, fileList);
      if (fileList.length > 0) {
        this.fileList = [fileList[fileList.length - 1]]  // 这一步,是展示最后一次选择的csv文件
        this.file = this.fileList[0].raw
      }
      // console.log(this.file);
      this.uploadStatus = true
    },
    async xlsDemoExport(){
      if (!this.file) {
        // return this.$message.error('请上传文件')
        return false
      }
      const formData = new FormData()
      formData.append('file', this.file)
      // 添加其他参数
      if(Object.values(this.otherUploadData).length > 0){
        for (let key in this.otherUploadData) {
          formData.append(key, this.otherUploadData[key])
        }
      }
      //  调用上传接口...
      this.$loading.show()
      // `${process.env.VUE_APP_BASE_BRAND_API}/v1/inspectionSpeechArt/importExcel
      upload.uploadFile(this.uploadFileUrl, formData).then(res => {
        if(res.code == 0){
          this.exportStatus = true
          this.tableData = res.item.failList.map(item => {
            let obj = {}
            obj.lineNum = item.lineNum
            obj.failReason = item .failReason
            obj.projectCode = item. projectCode
            return obj
          })
          this.failNum  = res.item.failNum
          this.successNum = res.item.successNum
        } else {
          this.$message.error(res.message)
        }
        this.$loading.hide()
      }).catch((error) => {
        console.log(error);
        this.$message.error('上传失败,请稍后再试或联系IT解决')
        this.$loading.hide()
      })
    },
  },
}
</script>

<style  lang="scss" scoped>
::v-deep .el-dialog{
  width: 25%;
  border-radius: 12px;
  margin-top:-8vh !important;
  top: 50%;
  transform: translateY(-50%);
}
::v-deep .el-dialog__header {
  border-bottom: 1px solid #efeff6;
  padding-left: 50px;
  .el-dialog__title,
  .el-dialog__headerbtn i {
    color: #36395c !important;
    font-size: 18px !important;
    font-weight: 600;
  }
}
</style>

<style lang="scss">
.export-standard-speech {
  .el-list-enter-active,
  .el-list-leave-active {
    transition: none;
  }
  .el-list-enter,
  .el-list-leave-active {
    opacity: 0;
  }
  .el-upload-list {
    height: 40px;
  }
  // 表格body
  .el-dialog__body{
    padding: 30px 100px;
  }
  // 导入
  .standard-export{
    .upload-demo-xls{
      width: 100%;
      margin-top: 20px;
    }
    .el-upload.el-upload--text{
      width: 100%;
    }
    .el-upload-dragger{
      width: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      border: 1px solid #EFEFF6;
      height: 120px;
      .el-upload__text{
        font-weight: 600;
        color: #36395C;
        .file-name{
          color: #4646E6;
        }
        .file-size{
          color: #CCCDD8;
        }
        .file-select{
          color: #4646E6;
          text-decoration: underline;
        }
      }
    }
    .export-title{
      font-size: 14px;
      color: #36395C;
      font-weight: 600;
      line-height: 20px;
    }
    .export-warning{
      font-size: 14px;
      color: #CCCDD8;
      line-height: 20px;
    }
    .export-download-btn{
      width: 165px;
      height: 36px;
      border: 1px solid #4646E6;
      color: #4646E6;
      opacity: 1;
      border-radius: 6px;
      display: flex;
      align-items: center;
      justify-content: center;
      margin: 20px 0 30px;
    }
  }

  // 导入失败的表格数据
  .fail-num{
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 24px;
    font-size: 16px;
    color: #36395C;
    font-weight: 600;
    span{
      color: #EF6E49;
      margin: 0 3px;
    }
  }
  .export-fail-table{
    width: 100%;
    height: 280px;
    border: 1px solid #EFEFF6;
    border-radius: 6px;
    padding: 0 20px;
    .export-fail-text{
      font-size: 14px;
      line-height: 20px;
      color: #36395C;
      font-weight: 600;
      margin-bottom: 20px;
      margin-top: 20px;
    }
    .el-table__row {
      height: 60px;
      td {
        padding: 0 30px;
      }
    }
    .has-gutter tr {
      height: 60px;
    }
    .has-gutter tr th {
      font-size: 14px;
      color: #333333;
      font-family: Arial;
      padding: 0 20px;
    }
    thead th {
      font-size: 14px;
      color: #333333;
      font-weight: 600;
      height: 40px;
      background: #F5F6FB;
    }
    // 滚动条的宽度
    .el-table__body-wrapper::-webkit-scrollbar {
      width: 6px; // 横向滚动条
      height: 6px; // 纵向滚动条
    }
    // 滚动条的滑块
    .el-table__body-wrapper::-webkit-scrollbar-thumb {
      background-color: #E2E2E2;
      border-radius: 3px;
    }
  }
  .success-img{
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: 103px;
  }
  .success-text{
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: 30px;
    margin-bottom: 50px;
    font-size: 16px;
    color: #36395C;
    font-weight: 600;
    span{
      color: #4646E6;
      margin: 0 3px;
    }
  }
}
</style>

页面使用:

只上传文件的形式

<template>
  <div class="upload">
  	<Button  text="批量导入"  background="#36395C" color="#fff" :icon="true"  @click.native="handleExportBtn" />
    
    // ...
    <ImportData
      :showDialogVisible="exportVisible"
      :downloadDemoUrl="downloadStandardSpeech"
      :uploadFileUrl="uploadFileUrl"
      @dialogVisible="closeVisible"
    />
  </div>
</template>

<script>
import ImportData from '@/views/components/ImportData.vue'

export default {
  name: "index",
  components: {
    ImportData,
  },
  data() {
    return {
      // 导入弹框显示和隐藏
      exportVisible: false,
      downloadStandardSpeech: `${process.env.VUE_APP_EXPORTDEOM_API}/fileResources/templates_standardSpeech.xlsx`, // 模板下载文件地址,
      uploadFileUrl: 'http://10.0.0.10:3000/v1/inspectionSpeechArt/importExcel' // 可以写在配置文件中
    };
  },
  computed: {
    userAccountID() {
      return this.$store.state.user.userAccountID;
    },
  },
  // created() {
  //   this.getDataList();
  //   this.getCheckType();
  // },
  activated() {
    this.getDataList();
    this.getCheckType();
  },
  watch:{},
  methods: {
    // 导入
    handleExportBtn(){
      this.exportVisible = true
    },
    // 关闭导入
    closeVisible(){
      this.exportVisible = false
      // 刷新列表等操作
    },
  },
};
</script>


<style lang="scss" scoped>
</style>

上传文件和其他必传参数的形式

<template>
  <div class="upload">
  	<Button  text="批量导入"  background="#36395C" color="#fff" :icon="true"  @click.native="handleExportBtn" />
    
    // ...
    <ImportData
      :showDialogVisible="exportVisible"
      :downloadDemoUrl="downloadStandardSpeech"
      :uploadFileUrl="uploadFileUrl"
      :otherUploadData="otherUploadData"
      @dialogVisible="closeVisible"
    />
  </div>
</template>

<script>
import ImportData from '@/views/components/ImportData.vue'

export default {
  name: "index",
  components: {
    ImportData,
  },
  data() {
    return {
      // 导入弹框显示和隐藏
      exportVisible: false,
      downloadStandardSpeech: `${process.env.VUE_APP_EXPORTDEOM_API}/fileResources/templates_standardSpeech.xlsx`, // 模板下载文件地址,
      uploadFileUrl: 'http://10.0.0.10:3000/v1/inspectionSpeechArt/importExcel',
      otherUploadData: {},
    };
  },
  computed: {
    userAccountID() {
      return this.$store.state.user.userAccountID;
    },
  },
  // created() {
  //   this.getDataList();
  //   this.getCheckType();
  //   this.otherUploadData = { key : 'value' };
  // },
  activated() {
    this.getDataList();
    this.getCheckType();
    this.otherUploadData = { key : 'value' };
  },
  watch:{},
  methods: {
    // 导入
    handleExportBtn(){
      this.exportVisible = true
    },
    // 关闭导入
    closeVisible(){
      this.exportVisible = false
      // 刷新列表等操作
    },
  },
};
</script>


<style lang="scss" scoped>
</style>

效果如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
封装 Element UI 的上传组件,你可以创建一个自定义的 Vue 组件,然后在其中使用 Element UI 的 el-upload 组件。以下是一个简单的封装示例: ```vue <template> <div> <el-upload ref="upload" :action="uploadUrl" :on-success="handleSuccess" :before-upload="beforeUpload" :auto-upload="autoUpload" > <slot></slot> </el-upload> </div> </template> <script> export default { name: 'CustomUpload', props: { uploadUrl: { type: String, required: true }, autoUpload: { type: Boolean, default: true } }, methods: { handleSuccess(response, file, fileList) { // 处理上传成功的回调逻辑 this.$emit('upload-success', response, file, fileList); }, beforeUpload(file) { // 可以在这里添加一些上传前的逻辑判断,如文件类型、大小等 return true; // 返回 true 表示允许上传 }, clearFiles() { this.$refs.upload.clearFiles(); }, abortUpload() { this.$refs.upload.abort(); } } }; </script> ``` 在这个示例中,我们创建了一个 `CustomUpload` 组件,它接受一个 `uploadUrl` 属性来指定上传地址,并且还有一个可选的 `autoUpload` 属性来控制是否自动上传。 你可以在组件中添加自定义的逻辑和样式,并使用 `this.$refs.upload` 来访问 Element UI 的上传组件实例,从而调用其方法和获取上传的文件信息。 使用示例: ```vue <template> <div> <custom-upload upload-url="上传地址" :auto-upload="false" @upload-success="handleUploadSuccess" > <el-button size="small" type="primary">点击上传</el-button> </custom-upload> </div> </template> <script> import CustomUpload from '@/components/CustomUpload.vue'; export default { components: { CustomUpload }, methods: { handleUploadSuccess(response, file, fileList) { console.log('上传成功'); } } }; </script> ``` 在上面的示例中,我们在 `CustomUpload` 组件中使用了一个插槽,用来插入自定义的上传按钮。当文件上传成功后,会触发 `upload-success` 事件,你可以在父组件中监听该事件并处理相应的逻辑。 这样,你就可以通过封装 Element UI 的上传组件来方便地在项目中使用了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值