需求

展示图片和PDF类型,并且点击图片或者PDF可以预览

第一步:遍历所有的图片和PDF列表

<div v-for="(data,index) in parerFont(item.fileInfo)" :key="index" class="data-list-item">
       <downloadCard :file-info="data" />
</div>

第二步:编写downloadcard组件

<template>
  <div class="download-card">
    <!-- 图片与PDF格式 -->
    <file-preview v-if="isImageOrPDF(fileInfo.url)" :url="fileInfo.url" :name="fileInfo.name" />
    <!-- ZIP XSLS WAP 等格式 -->
    <div v-else class="other-type">
      <div><d2-icon-svg name="transaction" class="iconrefresh" /></div>
      <div class="file-name-other">{{ fileInfo.name }}</div>
    </div>
    <div @click="donwload(fileInfo.url, fileInfo.name)">
      <d2-icon name="import" class="iconimport" />
    </div>
  </div>
</template>

<script>
import axios from 'axios';
import FilePreview from '@/components/file-preview';
export default {
  name: 'downloadCard',
  components: {
    FilePreview
  },
  props: {
    fileInfo: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
    };
  },
  created() {
  },
  methods: {
    justPDF(str) {
      var strRegex = '(.pdf)$'; // 用于验证后缀是否是pdf
      var reg = new RegExp(strRegex);
      if (reg.test(str.toLowerCase())) {
        // console.log('是pdf')
        return true;
      } else {
        // console.log('不是pdf')
        return false;
      }
    },
    isImageOrPDF(filename) {
      // 获取文件的扩展名
      const extension = filename.split('.').pop().toLowerCase();
      // 常见的图片和 PDF 文件扩展名
      const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'];
      const pdfExtensions = ['pdf'];
      // 检查文件扩展名是否在常见图片或 PDF 扩展名列表中
      return imageExtensions.includes(extension) || pdfExtensions.includes(extension);
    },
    donwload(fileUrl, fileName = '') {
      axios({
        method: 'get',
        url: fileUrl,
        responseType: 'blob',
      }).then((response) => {
        const link = document.createElement('a');
        const blob = new Blob([response.data], { type: response.data.type });
        const urlRef = window.URL.createObjectURL(blob);
        link.href = urlRef;
        link.download = fileName;
        link.click();
        window.URL.revokeObjectURL(urlRef);
      }).catch(err => {
        console.log(err);
      });
    }
  }
};
</script>

<style scoped lang="scss">
.download-card{
  padding: 12px;
  border-radius: 12px;
  border: 1px dashed rgba(234, 234, 234, 1);
  box-sizing: border-box;
  background: rgba(255, 255, 255, 1);
  display: flex;
  align-items: center;
  width: 235px;
  justify-content: space-between;
  color: rgba(114, 120, 128, 1);
  .file-name{
    width: 136px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    position: relative;
  }
  .file-name-other{
    width: 160px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    position: relative;
    margin-left: 5px;
  }
  .type-img{
    display: flex;
  }
  .type-pdf{
    display: flex;
  }
  .iconrefresh, .iconimport{
    width: 24px !important;
    height: 24px !important;
  }
  .other-type{
    display: flex;
    align-items: center;
    cursor: default;
  }
}
</style>

 第三步:编写FilePreview实现图片和PDF预览组件

<template>
  <div class="preview-wrap">
    <!-- PDF和图片类型点击 -->
    <div v-if="justPDF(url)" class="type-pdf" @click="previewFile(url)">
      <div><d2-icon-svg name="transaction" class="iconrefresh" /></div>
      <div class="file-name-pdf">{{ name }}</div>
    </div>
    <div v-else class="type-img" @click="previewFile(url)">
      <div>
        <img :src="url" class="type-img-preview" alt="">
      </div>
      <div class="file-name">{{ name }}</div>
      <div class="hover-pick">
        <img src="../../../public/image/merchant/Magnifying_glass.png" class="type-img-innner" alt="">
      </div>
    </div>
    <!-- PDF预览 -->
    <template v-if="pdfContainerVisible">
      <div id="pdf-container" />
      <div class="pdf-close" @click="pdfContainerVisible = false">
        <i class="el-icon-close" />
      </div>
    </template>
    <!-- 图片预览 -->
    <viewer
      v-else
      :options="{'toolbar': false, 'navbar': false, 'title': false}"
      :images="[url]"
      @inited="imagePreviewInited">
      <template slot-scope="scope">
        <img v-for="(src, index) in scope.images" :src="src" :key="index" style="display:none;">
      </template>
    </viewer>
  </div>
</template>

<script>
import Viewer from 'v-viewer/src/component.vue';
import 'viewerjs/dist/viewer.css';
// import MagnifyingGlass from '../../../public/image/merchant/Magnifying_glass.png';

import local from './local';

const SCOPE_NAME = 'siPreview';

export default {
  name: SCOPE_NAME,
  components: {
    Viewer,
  },
  inheritAttrs: false,
  props: {
    url: {
      type: String,
      default: '',
    },
    name: {
      type: String,
      default: '',
    },
    isImageBase64: false,
  },
  data() {
    return {
      pdfContainerVisible: false,
    };
  },
  created() {
    if (!this.$i18n.getLocaleMessage('en')[SCOPE_NAME]) {
      this.$i18n.mergeLocaleMessage('en', local.en);
      this.$i18n.mergeLocaleMessage('cn', local.cn);
    }
  },
  methods: {
    justPDF(str) {
      var strRegex = '(.pdf)$'; // 用于验证后缀是否是pdf
      var reg = new RegExp(strRegex);
      if (reg.test(str.toLowerCase())) {
        // console.log('是pdf')
        return true;
      } else {
        // console.log('不是pdf')
        return false;
      }
    },
    // 文件预览
    previewFile(fileUrl) {
      const fileExtension = fileUrl.split('.').pop();
      const isPdf = fileExtension.toLowerCase().startsWith('pdf');
      const isImg = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].find(suffix => fileExtension.toLowerCase().startsWith(suffix));
      if (isPdf) {
        this.pdfPreview(fileUrl);
      } else if (isImg || this.isImageBase64) {
        this.imagePreview();
      } else {
        window.open(fileUrl);
      }
    },
    // 图片预览
    imagePreview() {
      this.$viewer.show();
    },
    imagePreviewInited(viewer) {
      this.$viewer = viewer;
    },
    // PDG预览
    pdfPreview(fileUrl) {
      this.pdfContainerVisible = true;
      this.$nextTick(() => {
        let url = '';
        if (fileUrl.startsWith('http://')) {
          url = fileUrl.substring(5);
        } else if (fileUrl.startsWith('https://')) {
          url = fileUrl.substring(6);
        } else {
          url = fileUrl;
        }
        // eslint-disable-next-line no-undef
        PDFObject.embed(url, '#pdf-container', {
          width: '80%'
        });
      });
    }
  },
};
</script>

<style lang="scss" scoped>
  .preview-wrap {
    display: inline-block;
    width: 224px;
    // background: red;
    height: 30px;
    margin-right: 5px;
  }
  .preview-button {
    padding: 0;
  }
  #pdf-container {
    position: fixed;
    z-index: 10000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    background-color: rgba(0, 0, 0, 0.6);
  }
  .pdf-close {
    position: fixed;
    z-index: 10001;
    right: 0;
    top: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 60px;
    height: 60px;
    font-size: 40px;
    color: #fff;
    background-color: rgba(0, 0, 0, 0.4);
    cursor: pointer;
  }
  .file-name{
    width: 136px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    position: relative;
    margin-left: 5px;
  }
  .file-name-pdf{
    width: 156px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    position: relative;
    margin-left: 5px;
  }
  .hover-pick{
    position: absolute;
    top: 0;
    background: #000;
    margin-top: -6px;
    border-radius: 8px;
    width: 42px;
    height: 42px;
    border: none;
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden;
    opacity: 0.5;
    visibility: hidden;
  }
  .type-img{
    display: flex;
    height: 30px;
    align-items: center;
    position: relative;
    .type-img-preview{
      height: 40px;
      width:40px;
      object-fit: cover;
      margin-right: 5px;
      margin-top: 3px;
      border-radius: 8px;
      border: 1px solid #EAEAEA;
    }
    .type-img-innner{
      height: 15px;
      width:15px;
      z-index: 2;
    }
    &:hover{
      .hover-pick{
        visibility:visible;
      }
    }
  }
  .type-pdf{
    display: flex;
    height: 30px;
    align-items: center;
  }
  .iconrefresh{
    width: 24px !important;
    height: 24px !important;
  }
</style>

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部