index.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <template>
  2. <div class="basic-image">
  3. <template v-for="(image,index) in fileList" :key="index">
  4. <img-row :file="image"
  5. :config="config"
  6. :remove-code="config.removeCode"
  7. :removable="true"
  8. @preview="handlePictureCardPreview"
  9. @after-remove="removeFile"></img-row>
  10. </template>
  11. <el-upload action="uploadUrl"
  12. class="upload-plus"
  13. :accept="accept"
  14. :before-upload="beforeUpload"
  15. :http-request="uploadFile"
  16. :show-file-list="false"
  17. multiple>
  18. <div class="image-plus" v-if="isAppend"><i class="el-icon-plus"></i></div>
  19. <template #tip>
  20. <div class="el-upload__tip">{{limitTip}}</div>
  21. </template>
  22. </el-upload>
  23. <el-dialog title="图片预览" v-model="dialogVisible">
  24. <cip-dynamic-image style="width:100%" :src="dialogImageUrl" alt=""/>
  25. </el-dialog>
  26. </div>
  27. </template>
  28. <script>
  29. import { computed, ref } from 'vue'
  30. import { ElUpload, ElDialog } from 'element-plus'
  31. import CipDynamicImage from '../../../cip-dynamic-image'
  32. import ImgRow from './img-row'
  33. import { formInputProps } from '../../form-input-props'
  34. import { uploadProps } from '../file/upload'
  35. export default {
  36. props: formInputProps,
  37. components: { ElUpload, ElDialog, ImgRow, CipDynamicImage },
  38. emits: ['update:modelValue'],
  39. setup (props, context) {
  40. const { fileList, mainMessage, countLimit, typeLimit, sizeLimit, ...uploadUtils } = uploadProps(props, context)
  41. const dialogImageUrl = ref('')
  42. const dialogVisible = ref(false)
  43. // 验证文件是否可以上传
  44. const beforeUpload = (file) => {
  45. if (mainMessage(typeLimit(file), '图片上传类型超出限制') ||
  46. mainMessage(countLimit(file), '图片上传数量超出限制') ||
  47. mainMessage(sizeLimit(file), '图片上传大小超出限制')) {
  48. return false
  49. }
  50. }
  51. const handlePictureCardPreview = (file) => {
  52. dialogImageUrl.value = props.config.imgTemplate ? props.config.imgTemplate(file.url) : file.url
  53. dialogVisible.value = true
  54. }
  55. // 限制提示语
  56. const limitTip = computed(() => {
  57. const { fileType, size } = props.config
  58. if (!!fileType && !!size) return `只能上传${fileType}文件,且不超过${size}MB`
  59. if (!!fileType && !size) return `只能上传${fileType}文件`
  60. if (!fileType && !!size) return `只能上传不超过${props.config.size}MB的文件`
  61. return ''
  62. })
  63. // 根据数量控制新增按钮
  64. const isAppend = computed(() => {
  65. return (props.config?.limit ?? Infinity) > fileList.value.length
  66. })
  67. const accept = computed(() => {
  68. const fileType = props.config.fileType
  69. if (fileType) {
  70. return '.' + fileType.replace(/,\s?/g, ',.')
  71. }
  72. return 'image/*'
  73. })
  74. return {
  75. ...uploadUtils,
  76. fileList,
  77. beforeUpload,
  78. handlePictureCardPreview,
  79. dialogVisible,
  80. dialogImageUrl,
  81. isAppend,
  82. limitTip,
  83. accept
  84. }
  85. }
  86. }
  87. </script>
  88. <style lang="less" scoped>
  89. .basic-image{
  90. .image-plus{
  91. background-color: #fbfdff;
  92. border: 1px dashed #c0ccda;
  93. border-radius: 6px;
  94. box-sizing: border-box;
  95. width: 148px;
  96. height: 148px;
  97. cursor: pointer;
  98. line-height: 146px;
  99. vertical-align: top;
  100. text-align: center;
  101. i{
  102. font-size: 28px;
  103. color: #8c939d;
  104. }
  105. &:hover{
  106. border: 1px dashed #409eff;
  107. }
  108. }
  109. .upload-plus{
  110. display: inline-block;
  111. vertical-align: top;
  112. }
  113. }
  114. </style>