index.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <template>
  2. <el-upload ref="upload" :action="action" :headers="reactiveData.headers" :list-type="listType" name="file"
  3. :multiple="multiple" :data="data" :accept="accept" :show-file-list="showFileList" :before-upload="beforeUpload"
  4. :on-success="onSuccess" :on-error="onError" :before-remove="beforeRemove" :on-remove="handleRemove"
  5. :disabled="disabled">
  6. <div class="image" v-if="listType === 'picture-card'">
  7. <el-icon v-if="src === ''" size="28">
  8. <Plus />
  9. </el-icon>
  10. <el-image v-else :src="src" />
  11. </div>
  12. <el-button v-else :type="type" :loading="loading === 1">{{ title }}</el-button>
  13. </el-upload>
  14. </template>
  15. <script setup>
  16. import { getToken } from "@/utils/auth";
  17. const { proxy } = getCurrentInstance()
  18. const props = defineProps({
  19. // 上传路径
  20. url: {
  21. type: String,
  22. default: undefined
  23. },
  24. // 是否支持多文件上传
  25. multiple: {
  26. type: Boolean,
  27. default: false
  28. },
  29. // 额外参数
  30. data: {
  31. type: Object || Function,
  32. default: () => { }
  33. },
  34. // 上传类型
  35. listType: {
  36. type: String,
  37. default: 'text'
  38. },
  39. // 文件类型
  40. accept: {
  41. type: String,
  42. default: ''
  43. },
  44. // 是否显示上传列表
  45. showFileList: {
  46. type: Boolean,
  47. default: false
  48. },
  49. // 是否禁用
  50. disabled: {
  51. type: Boolean,
  52. default: false
  53. },
  54. // 图片
  55. src: {
  56. type: String,
  57. default: ''
  58. }
  59. })
  60. // 上传地址
  61. const baseUrl = ref(import.meta.env.VITE_APP_BASE_API)
  62. const action = ref(`${baseUrl.value}/common/upload`)
  63. const reactiveData = reactive({
  64. headers: { Authorization: "Bearer " + getToken() },
  65. // 上传文件
  66. form: [],
  67. })
  68. // 上传状态
  69. const loading = ref(false)
  70. const type = ref('primary')
  71. const title = ref('点击上传')
  72. // 上传之前
  73. function beforeUpload(file) {
  74. loading.value = true
  75. title.value = 'Loading'
  76. if (!props.multiple) {
  77. reactiveData.form.size = file.size
  78. reactiveData.form.name = file.name
  79. }
  80. }
  81. // 上传成功
  82. function onSuccess(file) {
  83. if (file.code === 200) {
  84. loading.value = false
  85. type.value = 'success'
  86. title.value = '上传成功'
  87. if (props.multiple) {
  88. file.data.map(i => reactiveData.form.push(i))
  89. } else {
  90. reactiveData.form.data = file
  91. }
  92. proxy.$emit('upload', reactiveData.form)
  93. } else {
  94. onError()
  95. }
  96. }
  97. // 文件移除之前
  98. function beforeRemove() {
  99. return proxy.$modal.confirm('是否删除?').then(
  100. () => true,
  101. () => false
  102. )
  103. }
  104. // 文件列表移除时
  105. function handleRemove(file) {
  106. let e = reactiveData.form.filter(i => i.name !== file.name)
  107. proxy.$emit('upload', e)
  108. }
  109. // 上传失败
  110. function onError() {
  111. loading.value = false
  112. type.value = 'danger'
  113. title.value = '上传失败'
  114. }
  115. // 重置组件
  116. function onRefresh() {
  117. type.value = 'primary'
  118. title.value = '点击上传'
  119. proxy.$refs.upload.clearFiles()
  120. }
  121. defineExpose({
  122. onRefresh
  123. })
  124. </script>
  125. <style lang="scss" scoped>
  126. .image {
  127. width: 148px;
  128. height: 148px;
  129. display: flex;
  130. justify-content: center;
  131. align-items: center;
  132. .el-image{
  133. height: 100%;
  134. }
  135. }
  136. </style>