vue3+ts+alioss+elementplus文件上传组件封装

<template>
  <div style="width: 500px">
    <el-upload
      class="upload-demo"
      multiple
      :accept="fileType"
      :limit="limitNum"
      :show-file-list="false"
      :http-request="uploadRequest"
    >
      <el-button type="primary">Click to upload</el-button>
      <template #tip>
        <div class="el-upload__tip">提示:只支持上传{{ tip }}格式文件</div>
        <div class="fileList" v-show="fileData !== ''">
          <div style="display: flex; vertical-align: middle">
            <el-icon style="margin: 8px"><Document /></el-icon>
            <div
              class="fileName"
              style="font-size: 12px; width: 500; overflow: hidden"
            >
              <el-tooltip
                class="box-item"
                effect="dark"
                content="点击此处将打开预览文件"
                placement="top"
              >
                <span class="text" @click="previewFile">
                  {{ fileData }}
                </span>
              </el-tooltip>
            </div>
            <el-tooltip
              class="box-item"
              effect="dark"
              content="点击删除"
              placement="top"
            >
              <el-icon
                class="icon_del"
                style="margin: 8px"
                v-show="fileData"
                @click.stop="deleteFile"
              >
                <Delete />
              </el-icon>
            </el-tooltip>
          </div>
        </div>
      </template>
    </el-upload>
    <!-- 预览弹框 -->
    <el-dialog
      v-model="dialogVisible"
      title="预览"
      width="40%"
      height="30vh"
      :before-close="handleClose"
      :close-on-click-modal="false"
      :destroy-on-close="true"
    >
      <div v-if="fileData.includes('mp3')">
        <audio style="width: 100%" controls :src="fileData"></audio>
      </div>
      <div v-else-if="fileData.includes('mp4')">
        <video style="width: 100%" controls :src="fileData"></video>
      </div>
    </el-dialog>
  </div>
</template>
<script lang="ts" setup>
import { ref, watchEffect } from 'vue'
import { reqAliOssUpload } from '@/api/aliOSS'
import axios from 'axios'

const props = defineProps({
  modelValue: {
    type: Array,
    default: Array,
  },
  fileType: {
    type: String,
    default: 'image/*,video/*',
  },
  reqUrl: {
    type: Number,
    default: null,
  },
  reqType: {
    type: String,
    default: '',
  },
  reqCategory: {
    type: String,
    default: '',
  },
  limitNum: {
    type: Number,
    default: 4,
  },
  tip: {
    type: String,
    default: '音频',
  },
})

const filesArray = ref()

//声明事件消息
const emits = defineEmits<{
  (e: 'update:modelValue', value: string): void
}>()

//保存图片内存临时地址
const fileData = ref('')
watchEffect(() => {
  fileData.value = props.modelValue as any
})

const uploadRequest = async (file: any) => {
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  const res = await reqAliOssUpload(props.reqUrl, {
    category: props.reqCategory,
    mediaType: props.reqType,
  })
  const data = res.data
  // 随机数
  const random = Math.floor(Math.random() * 10000)
  // 文件后缀
  const fileSuffix = file.file.name.split('.').pop()
  const params = {
    key: data.dir + `${Date.now()}_${random}.${fileSuffix}`,
    policy: data.policy,
    OSSAccessKeyId: data.accessid,
    success_action_status: '200',
    signature: data.signature,
    file: file.file,
  }
  const url = 'https://' + data.host
  const config = {
    headers: {
      'Content-Type': 'multipart/form-data',
      'Access-Control-Allow-Origin': '*',
    },
  }
  const uploadRes = await axios.post(url, params, config)
  console.log('uploadRes', uploadRes)
  const filePath = 'https://' + data.host + '/' + params.key
  filesArray.value = filePath
  emits('update:modelValue', filePath)
}

// 删除文件
const deleteFile = () => {
  emits('update:modelValue', '')
}

// 预览文件
const dialogVisible = ref(false)
const previewFile = (e: any) => {
  console.log('预览', e)
  dialogVisible.value = true
}
// 关闭bofang
const handleClose = () => {
  dialogVisible.value = false
  // 销毁弹框组件
}
</script>

<style lang="scss">
.fileList {
  // 鼠标移入背景变色且字体变色
  &:hover {
    background-color: #f5f7fa;
  }
  .icon_del {
    &:hover {
      color: #ef1e1e;
      cursor: pointer;
    }
  }
  .fileName {
    // 鼠标移入字体变色
    .text {
      &:hover {
        color: #409eff;
        text-decoration: underline;
        cursor: pointer;
      }
    }
  }
}
</style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以尝试以下步骤来封装一个Vue 3和TypeScript下使用Element Plus的表单提交组件: 1. 安装必要的依赖: - Vue 3:`npm install vue@next` - TypeScript:`npm install -D typescript` - Element Plus:`npm install element-plus` 2. 创建一个新的Vue组件,并为其选择一个合适的名称,例如`FormSubmit.vue`。 3. 在`FormSubmit.vue`文件中,导入必要的模块和样式: ```vue <template> <!-- 表单内容 --> </template> <script lang="ts"> import { defineComponent } from 'vue'; import { ElButton, ElForm, ElFormItem } from 'element-plus'; export default defineComponent({ components: { ElButton, ElForm, ElFormItem, }, }); </script> <style scoped> /* Element Plus 样式 */ @import 'element-plus/packages/theme-chalk/src/index.scss'; /* 自定义样式 */ /* ... */ </style> ``` 4. 在模板中编写表单内容,并使用Element Plus的组件来构建表单: ```vue <template> <el-form ref="form" :model="formData" label-width="120px"> <el-form-item label="姓名" prop="name"> <el-input v-model="formData.name"></el-input> </el-form-item> <!-- 更多表单项 --> <el-form-item> <el-button type="primary" @click="submitForm">提交</el-button> </el-form-item> </el-form> </template> <script lang="ts"> // ... export default defineComponent({ // ... data() { return { formData: { name: '', // 更多表单字段 } }; }, methods: { submitForm() { // 表单提交逻辑 if (this.$refs.form.validate()) { // 表单验证通过,执行提交操作 // ... } } } }); </script> ``` 这样,你就可以使用封装好的表单提交组件来方便地处理表单提交了。你可以根据实际需求添加更多的表单项,并在`submitForm`方法中实现你的提交逻辑。希望这可以帮到你!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值