vue3 封装一个图片预览和下载的组件

476 阅读1分钟

先上需求 根据后台返回文件后缀判断 是图片格式需要显示图片 并有点击放大功能 文件 根据文件后缀 选择相应的logo显示 并且点击可以下载

image.png

image.png

image.png

<template>
  <div class="imagOrfile">
    <div class="image-preview">
      <el-image v-for="(item,index) in srcList" :key="index" :src="item" :preview-src-list="srcList" :initial-index="1" fit="cover"></el-image> 
    </div>
    <div class="file_preview" v-for="(item,index) in hrefList" :key="index">
      <img :src="item.icon" />
      <a class="block" target="_blank" :href="item.filePath">{{ item.fileName }}</a>
    </div>
  </div>
</template>
<script setup>
// methods
import { defineProps, ref, watchEffect } from 'vue'
const srcList = ref([])
const hrefList = ref([])
//没有文件类型用unknow图标
const unkownPath = require('./images/unknow.png')
//设置不同的后缀显示不同的图片
const iconMap = [
  { icon: require('./images/csv.png'), exts: ['csv'] },
  { icon: require('./images/txt.png'), exts: ['txt'] },
  { icon: require('./images/pdf.png'), exts: ['pdf'] },
  { icon: require('./images/zip.png'), exts: ['zip', 'rar', '7z', 'tar', 'gz'] },
  { icon: require('./images/excel.png'), exts: ['xls', 'xlsx', 'xlsm'] },
  { icon: require('./images/ppt.png'), exts: ['ppt', 'pptx'] },
  { icon: require('./images/word.png'), exts: ['doc', 'docx'] }
]

const props = defineProps({
  files: {
    type: Array,
    defult: []
  },
  nameKey: {
    type: String,
    default: 'fileName'
  },
  pathKey: {
    type: String,
    default: 'filePath'
  }
})
const typsList = ['image/bmp', 'bmp', 'png', 'image/jpeg', 'jpeg', 'jpg', 'image/png', 'image/gif', 'gif', 'svg', 'image/webp', 'webp']
function compareImg(sysFiles) {
  srcList.value = []
  hrefList.value = []

  sysFiles.forEach(el => {
    if (el.filePath) {
      // 截取网址后缀
      let lastPathNum = el.filePath.lastIndexOf(".");//拿到网址'.’的下标
      let path = el.filePath.substr(lastPathNum + 1)//截取网址后缀
      if (typsList.indexOf(path) > -1) { // 说明类型是图片
        srcList.value.push(el.filePath)
      } else {
        var json = { fileName: '', filePath: '', icon: unkownPath }
        json.fileName = el[props.nameKey]
        json.filePath = el[props.pathKey]
        const iconObj = iconMap.find(icon => icon.exts.includes(path))
        if (iconObj) {
          json.icon = iconObj.icon
        }
        hrefList.value.push(json)
      }
    }

  })
}
watchEffect(() => {
  compareImg(props.files || [])
})
</script>
<style lang='scss' scoped>
.el-image {
  margin-right: 10px;
  width: 50px;
  height: 50px;
}

.file_preview {
  display: flex;
  & + .file_preview {
    margin-top: 10px;
  }
  img {
    height: 20px;
    width: 20px;
    margin-right: 10px;
  }
  a {
    line-height: 20px;
  }
}
</style>

使用

1.引入

import FileList from '_src/components/common/FileList'

2.使用

  <FileList :files="data.catalogue"></FileList>