26、vue项目 文件附件的预览、下载和动态删除组件(仅查看无上传)——包含mp4预览,mp3预览,图片预览,PDF预览等

文件附件的预览、下载和动态删除组件(仅查看无上传)

需求

需求是从后端拿到了一个数组的图片,文档,视频或者音频的数组
最后的使用样式截图放最后了
比如

fileList: [
        '/upload/332131.png',
        '/upload/sale?filename=csdacsa.pdf',
        '/upload/sale?filename=才能打死啊.xlx',
        '/upload/sale?filename=3.png',
        '/upload/sale?filename=吃的啥.gif',
        '/upload/sale?filename=除非是打完钱.zip',
        '/upload/等我if差动.mp4',
        '/upload/sale?filename=从电脑哦vcdai.mp3'
      ]

需要能够渲染到页面上后,能够预览,包括mp4,png,mp3,jpg等,其中的视频和音频的播放都是写死的,从网上找的测试的文件,如果是后端有具体的返回的话自己进行拼接一下即可
在这里插入图片描述

文件list列表显示组件代码

其中需要安装视频播放的插件,在项目根目录终端运行
npm install --save video.js

在当前需要使用的页面导入,这里就不使用全局了(绝不是因为我使用全局一直报错 /(ㄒoㄒ)/~~)
import 'video.js/dist/video-js.css'

当前代码的import VideoJs from './VideoJs.vue'指的是在同级目录下的组件,也就是下面的VideoJs.vue文件

file-list.vue文件代码

<template>
  <div class="file-list">
    <div v-for="(item, index) in fileLists" :key="index" class="file">
      <div class="icon">
        <img v-if="getFileType(item) === 'xls' || getFileType(item) === 'xlsx'" src="@/static/file-icon/xls.png">
        <img v-else-if="getFileType(item) === 'doc' || getFileType(item) === 'docx'" src="@/static/file-icon/doc.png">
        <img v-else-if="getFileType(item) === 'mp3'" src="@/static/file-icon/mp3.png">
        <img v-else-if="getFileType(item) === 'mp4'" src="@/static/file-icon/mp4.png" @click="seeMp4(item)">
        <img v-else-if="getFileType(item) === 'pdf'" src="@/static/file-icon/pdf.png">
        <img v-else-if="getFileType(item) === 'ppt' || getFileType(item) === 'pptx'" src="@/static/file-icon/ppt.png">
        <img v-else-if="getFileType(item) === 'txt'" src="@/static/file-icon/txt.png">
        <img
          v-else-if="getFileType(item) === '7z' || getFileType(item) === 'zip' || getFileType(item) === 'rar'"
          src="@/static/file-icon/package.png"
        >
        <template v-else-if="getFileType(item) === 'jpg' || getFileType(item) === 'png' || getFileType(item) === 'gif'">
          <viewer>
            <img :src="baseUrl + item">
          </viewer>
        </template>
        <img v-else src="@/static/file-icon/other.png">
      </div>
      <el-button type="text" class="name" @click="check(item)">
        {
   
   { item }}
      </el-button>
      <div class="action">
        <a class="action-download" :href="baseUrl + item" download="" target="_self">下载</a>
        <span class="del" @click="handleDelete(index)">删除</span>
      </div>
      <!-- 弹窗预览文件 -->
      <el-dialog
        v-if="accessoryVisble"
        :visible.sync="accessoryVisble"
        :show.sync="accessoryVisble"
        width="60%"
        class="accessoryVisble"
        :before-close="cancel"
        top="40px"
        :title="checkFile"
        append-to-body
      >
        <div class="dialog">
          <div v-if="fileType === 1">
            <img :src="baseUrl + checkFile" width="100%" />
          </div>
          <div v-else-if="fileType === 2" class="audio-mp3">
            <audio controls ref="audio" class="aud">
              <source src="http://music.163.com/song/media/outer/url?id=447925558.mp3" />
            </audio>
          </div>
          <div class="videoArea" v-else-if="fileType === 3">
            <video-js :options="videoOptions" class="video-css" />
          </div>
          <div v-else-if="fileType === 5">
            <!-- <iframe :src="baseUrl + checkFile" frameborder="e" width="100%" height="600" /> -->
            <!-- 测试链接 -->
            <iframe :src="'http://www.leomay.com/upload/file/mmo-20170707165001.pdf'" frameborder="e" width="100%" height="600" />
          </div>
        </div>
      </el-dialog>
    </div>
  </div>
</template>

<script>
// 视频播放插件
import VideoJs from './VideoJs.vue'
import 'video.js/dist/video-js.css'
export default {
  name: 'fileList',
  props: {
    list: {
      type: [Array],
      default: () => []
    }
  },
  components: {
    VideoJs
  },
  data() {
    return {
      baseUrl: '/upload/sale?filename=',  // 这里需要使用自己的后端的基础地址
      fileLists: [],
      accessoryVisble: false,
      checkFile: '',
      fileType: null,
      /**
       *播放器配置,如果还需要其他的则再加
      */
      videoOptions: {
        controls: true, // 开启交互,即是用户可控。
        muted: true, // 开启视频时是否静音
        fluid: true, // 根据外层css样式大小,自动填充宽高!比较实用,可搭配响应式
        reload: 'auto', // 重载
        // 其余设置根据需求添加!
        poster: require('@/static/file-icon/mp4.png'), // 视频封面
        sources: [ // 视频播放源,建议本地
          {
            // 测试地址网上找的
            src: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4',
            type: 'video/mp4'
          }
        ]
      }
    }
  },
  created() {
    // 获取文件名字格式列表
    for (let i = 0; i < this.list.length; i++) {
      console.log(this.getFileName(this.list[i]))
      this.fileLists.push(this.getFileName(this.list[i]))
      console.log(this.fileLists)
    }
  },
  methods: {
  	// 获取文件名字(分情况获取)
    getFileName(val) {
      if (val && val.indexOf('?filename=') !== -1) {
        console.log(val.substr(val.indexOf('?filename=') + 10))
        return val.substr(val.indexOf('?filename=') + 10)
      } else if (val && val.indexOf('upload/') !== 0) {
        const url = val.split('?')[0] // 只要?号前的
        const urlSlashCount = url.split('/').length // 统计斜杠
        console.log(url.split('/')[urlSlashCount - 1].toLowerCase())
        return url.split('/')[urlSlashCount - 1].toLowerCase() // 获取数组最后一个
        // return val
      } else {
        return val
      }
    },
    handleDelete(index) {
      console.log('删除', index)
      this.list.splice(index, 1)
    },
    handleDownload(index) {
      console.log('下载', index)
    },
    check(item) {
      console.log('预览', this.getFileType(item))
      this.checkFile = item
      this.accessoryVisble = true
      if (this.getFileType(item) === 'jpg' || this.getFileType(item) === 'png' || this.getFileType(item) === 'gif') {
        this.fileType = 1
        console.log('图片')
      } else if (this.getFileType(item) === 'mp3') {
        console.log('音频')
        this.fileType = 2
      } else if (this.getFileType(item) === 'mp4') {
        console.log('视频', this.videoOptions.sources[0].src)
        this.fileType = 3
        // this.videoOptions.sources.src[0] = this.baseUrl + item
      } else if (this.getFileType(item) === '7z' || this.getFileType(item) === 'zip' || this.getFileType(item) === 'rar') {
        console.log('压缩文件')
        this.checkFile = '该文件不可预览'
      } else {
        console.log('其他文件')
        this.fileType = 5
      }
    },
    cancel() {
      this.accessoryVisble = false
      this.otherFile = false
      this.isImage = false
      this.fileType = null
      this.checkFile = ''
    },
    //  获取文件格式
    getFileType(val) {
      const list = val.split('.')
      const type = list[list.length - 1]
      return type.toLowerCase()
    },
    seeMp4(item) {
      window.open(this.$settings.apiUrl + item)
    }
  }
}
</script>

<style lang="scss" scoped>
.file {
  display: flex;
  height: 48px;
  line-height: 48px;
  margin-bottom: 10px;

  .icon {
    margin-right: 10px;
    cursor: pointer;

    img {
      height: 48px;
      width: 36px;
      object-fit: cover;
    }
  }

  .name {
    flex: 1;
    display: flex;
    justify-content: flex-start;
  }

  .action {
    .del {
      color: red;
      cursor: pointer;
    }
    a {
      text-decoration-line: none;
      margin-right: 20px;
    }
      a:hover {
        text-decoration-line: underline;
      }
  }
}
  .dialog {
    width: 100%;
    // margin: auto;
    // display: flex;
    justify-content: center;
    align-items: center;
    margin-right: 20px;
    // height: auto;
    .videoArea {
      height: 100%;
    }
    .audio-mp3 {
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
</style>
<style>
单独给视频的播放按钮键设置位置
.video-js .vjs-big-play-button {
  top: 45%;
  left: 45%;
}
</style>

视频播放组件VideoJs.vue

<template>
  <div>
    <video ref="videoPlayer" class="video-js"></video>
  </div>
</template>

<script>
import 'video.js/dist/video-js.css'
import videojs from 'video.js'
export default {
  // name: 'VideoJs',
  props: {
    options: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  data() {
    return {
      player: null
    }
  },
  mounted() {
    this.player = videojs(this.$refs.videoPlayer, this.options, function onPlayerReady() {
      console.log('onPlayerReady', this)
    })
  },
  beforeDestroy() {
    if (this.player) {
      this.player.dispose()
    }
  }
}
</script>

<style scoped>
</style>

父组件引用

传入最上面的fileList数组即可

<template>
  <div>
    <file-list :list="fileList" />
  </div>
</template>

<script>
import fileList from './file-list.vue'
export default {
  components: {
    fileList
  },
  data() {
    return {
      fileList: [
         '/upload/332131.png',
        '/upload/sale?filename=csdacsa.pdf',
        '/upload/sale?filename=才能打死啊.xlx',
        '/upload/sale?filename=3.png',
        '/upload/sale?filename=吃的啥.gif',
        '/upload/sale?filename=除非是打完钱.zip',
        '/upload/等我if差动.mp4',
        '/upload/sale?filename=从电脑哦vcdai.mp3'
        '从电脑哦vcdai.mp3'
      ]
    }
  }
}
</script>

<style>

</style>

音频播放

在这里插入图片描述

视频播放

在这里插入图片描述

文件查看

文件查看没有仔细调整,可自己测试测试
在这里插入图片描述

图片查看

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44035882/article/details/127531057