element-plus实现文件点击上传UI

5 篇文章 0 订阅

实现如下功能,点击这个按钮,文件直接上传
在这里插入图片描述
思路, upload组件会显示待上传文件, 样式不统一

使用事件委托, 将upload组件隐藏起来


<template>
  <div class="device-code-container">
    <h1>Register Your Device</h1>
    <div>
      Input the code
    </div>
    <el-input v-model.trim="input" placeholder="e.g. BADWDR" class="input-box" />
    <el-button type="primary" @click="handleClick" class="device-code-button" size="large">Continue</el-button>
  </div>

  <div>My Device:</div>
  <el-table :data="deviceTableData" style="width: 100%">
    <el-table-column prop="mac" label="MAC" width="180" />
    <el-table-column prop="filename" label="logo file" width="500" />
    <el-table-column prop="status" label="status" width="80" />
    <el-table-column prop="option" label="option" width="120">
      <template #default="{ row }">
        <el-upload class="option-button" action="" v-model:file-list="fileList" :limit="1" :on-change="handleChange"
          :on-remove="handleRemove" :auto-upload="false" accept="image/jpeg" style="display:none">
          <template #trigger>
            <el-button class="upload-button"></el-button>
          </template>
        </el-upload>

        <el-button :icon="Upload" type="success" size="small" @click="triggerUpload(row)" :loading="buttonLoading">
        </el-button>
        <el-button slot="tip" class="option-button" type="danger" size="small" :icon="Delete"
          @click="delMacLine(row)" />
      </template>
    </el-table-column>
  </el-table>
</template>

<script setup>
import { ref, watch } from 'vue'
import { verifyDeviceCode } from '@/api/upgrade'
import { queryMacList, deleteMacRecord } from '@/api/machine'
import { Delete, Upload } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import instance from '@/api/instance'

const buttonLoading = ref(false)
const fileList = ref([])
const uploadMac = ref('')

function getEncode64(str) {
  // 对字符串进行编码
  const encode = encodeURI(str)
  // 对编码的字符串转化base64
  const base64 = btoa(encode)
  return base64
}

function triggerUpload(row) {
  uploadMac.value = row.mac
  document.querySelector('.upload-button').click()
}

const submitUpload = () => {
  if (fileList.value.length === 0) {
    ElMessage({
      showClose: true,
      message: 'Oops, please select one file.',
      type: 'error'
    })
    return
  }

  buttonLoading.value = true

  // 文件以FormData形式传给服务器
  const filesPromise = fileList.value.map((item) => {
    const formData = new FormData()
    const filename = getEncode64(item.name)
    formData.append('file', item.raw, filename)
    formData.append('mac', uploadMac.value)

    return axios({
      url: '/upload_single',
      method: 'POST',
      data: formData,
    }).then((res) => {
      ElMessage({
        showClose: true,
        message: `${item.name} 上传成功`,
        type: 'success'
      })
      updateLists()
    })
      .catch((err) => {
        ElMessage({
          showClose: true,
          message: `${err.message}, 上传失败`,
          type: 'error'
        })
      })
      .finally(() => {
        buttonLoading.value = false
        fileList.value = []
      })
  })

  Promise.all(filesPromise)
}

watch(fileList, (newFileList) => {
  if (newFileList.length === 1) {
    submitUpload()
  }
})

const handleChange = (file, files) => {
  if (!file) {
    ElMessage({
      showClose: true,
      message: `未找到文件`,
      type: 'error'
    })
    fileList.value = []
    return
  }

  if (!['image/jpg', 'image/jpeg'].includes(file.raw.type) || name.includes('jpg')) {
    ElMessage({
      showClose: true,
      message: `文件不为jpg格式`,
      type: 'error'
    })
    fileList.value = []
    return
  }
}

const handleRemove = (file, files) => {
  if (!file) return
  const removeFilename = file.name

  fileList.value = fileList.value.filter(item => {
    return item.name !== removeFilename
  })
}

const deviceTableData = ref([])
const input = ref('')

function handleClick() {
  verifyDeviceCode(input.value).then((res) => {
    updateLists()
    ElMessage({
      message: res.msg,
      type: 'success'
    })
  })
}

function updateLists() {
  queryMacList().then((res) => {
    console.log('[long] res: ', res)
    res.forEach((item, index) => {
      res[index].url = `${import.meta.env.VITE_APP_BASE_API}/upgrade/${item.mac}`
    })
    deviceTableData.value = res
  })
}
updateLists()

function delMacLine(row) {
  deleteMacRecord(row).then((res) => {
    updateLists()
  })
}

</script>

<style lang="scss" scoped>
.device-code-container {
  border: 2px solid rgba(124, 106, 106, 0.712);
  border-radius: 6px;
  padding: 10px;
  width: 400px;
  margin: 30px auto;
  text-align: center;

  .input-box {
    width: 300px;
    margin: 10px;
  }

  .device-code-button {
    width: 300px;
    margin-bottom: 10px;
  }
}

:deep(.el-upload) {
  display: inline-block;
}

.option-button {
  display: inline-block;
  margin: 5px;
}
</style>

自行修改

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值