当前位置:   article > 正文

Vue 封装el-upload通用组件, 实现pdf、img混排,支持预览_el-upload上传pdf可预览

el-upload上传pdf可预览
  1. 使用vue-pdf加载pdf文件
    npm install --save vue-pdf
  2. el-upload设置上传文件格式,自定义排版,通过过slot实现
     

    1. <el-upload
    2. ref="elUpload"
    3. :action="baseUrl"
    4. list-type="picture-card"
    5. :limit="limit"
    6. :class="{ hide: disabled }"
    7. :disabled="disabled"
    8. :before-upload="beforeAvatarUpload"
    9. accept=".jpg, .png, .gif, .jpeg, .pdf"
    10. :file-list="fileList"
    11. >
    12. <i class="el-icon-plus"></i>
    13. <div
    14. slot="file"
    15. slot-scope="{ file }"
    16. v-loading="file.status == 'uploading'"
    17. style="height: 100%"
    18. >
    19. <pdf
    20. v-if="file.name.endsWith('.pdf')"
    21. :src="file.url"
    22. :page="1"
    23. ></pdf>
    24. <img
    25. v-else
    26. class="el-upload-list__item-thumbnail"
    27. style="object-fit: cover"
    28. :src="file.url"
    29. alt=""
    30. />
    31. <spa class="el-upload-list__item-actions">
    32. <span
    33. class="el-upload-list__item-preview"
    34. @click="handlePictureCardPreview(file)"
    35. >
    36. <i class="el-icon-zoom-in"></i>
    37. </span>
    38. <span
    39. v-if="!disabled"
    40. class="el-upload-list__item-delete"
    41. @click="handleRemove(file)"
    42. >
    43. <i class="el-icon-delete"></i>
    44. </span>
    45. </spa>
    46. </div>
    47. </el-upload>

  3. pdf预览,通过el-dialog 实现
     

    1. <el-dialog
    2. title="查看PDF"
    3. :visible.sync="dialogVisible"
    4. width="80%"
    5. :modal="false"
    6. >
    7. <pdf
    8. ref="pdf"
    9. v-for="i in pdfPageNumber"
    10. :key="i"
    11. :src="pdfSrc"
    12. :page="i"
    13. ></pdf>
    14. </el-dialog>

  4. 图片预览,为了和项目图片预览保持统一,这里使用el-image自带的图片预览,不过需要自己手动调用
     

    1. //设置一个1像素的,为了使用预览功能
    2. <el-image
    3. ref="elImage"
    4. :src="previewImageUrl"
    5. style="width: 1px; height: 1px"
    6. :preview-src-list="[previewImageUrl]"
    7. ></el-image>
    8. //获取elImage元素,手动调用预览
    9. let image = this.$refs.elImage;
    10. image.showViewer = true;

  5. 效果图

  6. 完整代码

     

  1. <template>
  2. <div>
  3. <div style="display: flex; flex-direction: column">
  4. <el-upload
  5. ref="elUpload"
  6. :action="baseUrl"
  7. list-type="picture-card"
  8. :limit="limit"
  9. :class="{ hide: disabled }"
  10. :disabled="disabled"
  11. :before-upload="beforeAvatarUpload"
  12. accept=".jpg, .png, .gif, .jpeg, .pdf"
  13. :file-list="fileList"
  14. >
  15. <i class="el-icon-plus"></i>
  16. <div
  17. slot="file"
  18. slot-scope="{ file }"
  19. v-loading="file.status == 'uploading'"
  20. style="height: 100%"
  21. >
  22. <pdf
  23. v-if="file.name.endsWith('.pdf')"
  24. :src="file.url"
  25. :page="1"
  26. ></pdf>
  27. <img
  28. v-else
  29. class="el-upload-list__item-thumbnail"
  30. style="object-fit: cover"
  31. :src="file.url"
  32. alt=""
  33. />
  34. <spa class="el-upload-list__item-actions">
  35. <span
  36. class="el-upload-list__item-preview"
  37. @click="handlePictureCardPreview(file)"
  38. >
  39. <i class="el-icon-zoom-in"></i>
  40. </span>
  41. <span
  42. v-if="!disabled"
  43. class="el-upload-list__item-delete"
  44. @click="handleRemove(file)"
  45. >
  46. <i class="el-icon-delete"></i>
  47. </span>
  48. </spa>
  49. </div>
  50. </el-upload>
  51. <p v-if="!disabled">
  52. 支持jpg、gif、png、pdf格式,最多上传10个,单个文件不超过20M。
  53. </p>
  54. <el-image
  55. ref="elImage"
  56. :src="previewImageUrl"
  57. style="width: 1px; height: 1px"
  58. :preview-src-list="[previewImageUrl]"
  59. ></el-image>
  60. </div>
  61. <el-image
  62. ref="elImage"
  63. :src="previewImageUrl"
  64. style="width: 1px; height: 1px"
  65. :preview-src-list="[previewImageUrl]"
  66. ></el-image>
  67. <el-dialog
  68. title="查看PDF"
  69. :visible.sync="dialogVisible"
  70. width="80%"
  71. :modal="false"
  72. >
  73. <pdf
  74. ref="pdf"
  75. v-for="i in pdfPageNumber"
  76. :key="i"
  77. :src="pdfSrc"
  78. :page="i"
  79. ></pdf>
  80. </el-dialog>
  81. </div>
  82. </template>
  83. <script>
  84. import pdf from "vue-pdf";
  85. export default {
  86. name: "",
  87. components: {
  88. pdf,
  89. },
  90. props: {
  91. ///当前列表选中条目
  92. selectRow: {
  93. type: Object,
  94. default: {},
  95. },
  96. //需要回显的文件
  97. fileList: {
  98. type: Array,
  99. default: [],
  100. },
  101. //最大上传数
  102. limit: {
  103. type: Number,
  104. default: 10,
  105. },
  106. ///是否禁用上传,只支持放大预览
  107. disabled: {
  108. type: Boolean,
  109. default: false,
  110. },
  111. },
  112. data() {
  113. return {
  114. pdfPageNumber: 0,///pdf最页数
  115. pdfSrc: "",///pdf地址
  116. loadingBtn: false,
  117. dialogVisible: false,
  118. previewImageUrl: "",///预览图片都中
  119. baseUrl: "",
  120. };
  121. },
  122. mounted() {
  123. this.getBaseUrl();
  124. },
  125. methods: {
  126. ///获取上传文件地址
  127. getBaseUrl() {
  128. if (process.env.NODE_ENV === "development") {
  129. this.baseUrl =
  130. "java/" +
  131. this.$store.state.user.urlConfig["java"] +
  132. "api/v1/app/aliyun/uploadFile";
  133. } else {
  134. this.baseUrl =
  135. this.$store.state.user.urlConfig["java"] +
  136. "api/v1/app/aliyun/uploadFile";
  137. }
  138. },
  139. ///判断文件大小
  140. beforeAvatarUpload(file) {
  141. const isLt20M = file.size / 1024 / 1024 < 20;
  142. if (!isLt20M) {
  143. this.$message.error("上传头像图片大小不能超过 20MB!");
  144. }
  145. return isLt20M;
  146. },
  147. ///点击删除
  148. handleRemove(file) {
  149. let uploadFiles = this.$refs.elUpload.uploadFiles;
  150. let index = uploadFiles.findIndex((item) => {
  151. return item == file;
  152. });
  153. uploadFiles.splice(index, 1);
  154. },
  155. ///预览
  156. handlePictureCardPreview(file) {
  157. if (file.name.endsWith(".pdf")) {
  158. if (file.response) {
  159. this.pdfSrc = file.response.data;
  160. } else {
  161. this.pdfSrc = file.name;
  162. }
  163. this.getPDFnums(this.pdfSrc);
  164. } else {
  165. let image = this.$refs.elImage;
  166. if (file.response) {
  167. this.previewImageUrl = file.response.data;
  168. } else {
  169. this.previewImageUrl = file.name;
  170. }
  171. image.showViewer = true;
  172. }
  173. },
  174. //计算pdf页码总数
  175. getPDFnums(url) {
  176. let loadURL = pdf.createLoadingTask({
  177. url: url, //你的pdf地址
  178. });
  179. loadURL.promise.then((pdf) => {
  180. this.pdfPageNumber = pdf.numPages;
  181. this.dialogVisible = true;
  182. });
  183. },
  184. getFileUrls() {
  185. let fileNames = "";
  186. const uploadFiles = this.$refs.elUpload.uploadFiles;
  187. debugger
  188. let uploading = uploadFiles.some((item) => {
  189. return item.status == "uploading";
  190. });
  191. if (uploading) {
  192. this.$message.warning("文件上传中,请稍后再试!");
  193. return false;
  194. }
  195. uploadFiles.forEach((item) => {
  196. const response = item.response;
  197. if (response) {
  198. if (response.code == 0) {
  199. fileNames += response.data + ",";
  200. }
  201. } else {
  202. fileNames += item.name + ",";
  203. }
  204. });
  205. if (fileNames.endsWith(",")) {
  206. fileNames = fileNames.replace(/,$/gi, "");
  207. }
  208. return fileNames;
  209. },
  210. },
  211. };
  212. </script>
  213. <style lang='less' scoped>
  214. /deep/ .hide .el-upload--picture-card {///deep 穿透隐藏上传图片入口
  215. display: none;
  216. }
  217. </style>

PS:pdf有些发票信息显示不全,一些字体显示不出来,解决办法如下

  1. //url 是当前pdf的链接地址
  2. getPdfUrl(url) {
  3. let src = pdf.createLoadingTask({
  4. url: url,
  5. //引入pdf.js字体,templ
  6. cMapUrl: "https://cdn.jsdelivr.net/npm/pdfjs-dist@2.5.207/cmaps/",
  7. cMapPacked: true,
  8. });
  9. return src;
  10. },

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/218942?site
推荐阅读
相关标签
  

闽ICP备14008679号