vue3、elementplus封装图片上传组件

父组件

<!-- 文件上传组件 -->
<template>
  <div>
    <el-upload
      :class="{ hide: props.fileList?.length>=props.limit }"
      :action="uploadUrl"
      :accept="accept"
      v-model:file-list="waitFileList"
      list-type="picture-card"
      :before-upload="beforeUploadHandle"
      :on-success="successHandle"
      :on-preview="handlePictureCardPreview"
      :on-error="handleError"
      :on-remove="handleRemove"
    >
      <el-icon class="avatar-uploader-icon"><Plus /></el-icon>
      <template v-if="tip" #tip>
        <span class="tip">&nbsp;{{ tip }}</span>
      </template>
    </el-upload>
    <el-dialog v-model="dialogVisible">
      <img w-full :src="dialogImageUrl" alt="Preview Image" />
    </el-dialog>
  </div>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { Plus } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { getToken } from '@/utils/cache'
import { useAppStore } from '@/store'
import { IObject } from "@/types/interface";

// 租户id和code
const store = useAppStore()
const { state } = store

const uploadUrl = computed(() => {
  return `${import.meta.env.VITE_APP_API}/sys/oss/upload?token=${getToken()`
})

/**
 * accept 文件类型
 * limit 文件数量限制
 * tip 提示文案
 */
const props = defineProps({
  fileList: {
    default: [],
    type: Array
  },
  accept: {
    type: String,
    default: 'image/jpeg,image/jpg,image/png'
  },
  limit: {
    type: Number,
    default: 5
  },
  tip: String
})
let waitFileList:any = ref([])
waitFileList.value = props.fileList
watch(
  () => props.fileList,
  () => {
    waitFileList.value = props.fileList
  }
)

const emit = defineEmits(["uploadSuccess","uploadChange"])

const getUrlParams = (url:string) => {
  let urlStr = url.split('?')[1]
  const urlSearchParams = new URLSearchParams(urlStr)
  const result = Object.fromEntries(urlSearchParams.entries())
  return result
}
// 校验文件类型
const beforeUploadHandle = (rawFile:any) => {
  if (rawFile.type !== 'image/jpeg'&&rawFile.type !== 'image/jpg'&&rawFile.type !== 'image/png') {
    ElMessage.error('请上传jpeg或jpg或png格式的图片!')
    return false
  } else if (rawFile.size / 1024 / 1024 > 10) {
    ElMessage.error('上传图片大小不能超过 10MB!')
    return false
  }
  return true
}

// 上传成功
const successHandle = (res: IObject, file: IObject, list: IObject[]) => {
  if (res.code !== 0) {
    waitFileList.value.pop()
    return ElMessage.error(res.msg)
  }
  emit("uploadSuccess", {
    name: getUrlParams(res.data.src).filename,
    url: res.data.src
  })
  ElMessage.success({
    message: '上传成功'
  })
}


const handleError = ()=>{
  ElMessage.error('上传失败')
}

const handleRemove = (uploadFile:any,uploadFiles:any)=>{
  const obj = props.fileList.filter((item:any)=>item.name!==uploadFile.name)
  emit("uploadChange", obj)
}



// 显示图片
const dialogVisible = ref(false)
const dialogImageUrl = ref('')
const handlePictureCardPreview = (uploadFile:IObject) => {
  dialogImageUrl.value = uploadFile.url
  dialogVisible.value = true
}


</script>
<style lang="less" scoped>
:deep(.el-upload-list__item.is-success:focus:not(:hover)){
  display: none !important;
}

:deep(.hide .el-upload--picture-card) {
  display: none;
}

.tip{
  color: #999999;
  font-size: 14px;
  padding-left: 12px;
  display: inline-block;
  transform: translateY(15px);
}
</style>

子组件

          <vpImgUpload :fileList="replyImg" @uploadSuccess="handleUploadSuccess" @uploadChange="handleUploadChange"></vpImgUpload>
const handleUploadSuccess = (file:any)=>{
  replyImg.value.push(file)
}
const handleUploadChange = (files:any)=>{
  replyImg.value = files
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值