我是靠谱客的博主 神勇钢笔,最近开发中收集的这篇文章主要介绍根据element改造的文件预览组件:支持图片、doc、xlsx、ppt、PDF、视频等文件预览,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

element-ui框架的预览只能预览图片,其他文件不支持,不支持就自己封装一个吧,前提条件后端返回的文件预览支持访问

首先在component中新建文件:FilePreview.vue:内容如下

<template>
  <!-- 预览组件 -->
  <div class="FilePreview">
    <div class="container">
      <!-- 渲染层 -->
      <div class="object" v-if="TragetObj.format == 'jpg' || TragetObj.format == 'png' || TragetObj.format == 'JPG' || TragetObj.format == 'PNG' || TragetObj.format == 'jpeg'|| TragetObj.format == 'tiff'|| TragetObj.format == 'swf'|| TragetObj.format == 'gif'|| TragetObj.format == 'JPEG'|| TragetObj.format == 'GIF'"
        ref="imgWrap" @mousewheel.prevent="rollImg">   
          <img class="Target modal-img" ref="img" @mousedown="moveImg" :src="TragetObj.url" alt="" >
      </div>
      <!-- 视频 -->
      <div class="object" v-else-if="TragetObj.format == 'webm' || TragetObj.format == 'mov' || TragetObj.format == 'mp4'">
        <video class="Target" controls="controls" width="1200" height="700" :src="TragetObj.url" autoplay ref="videoref" >
          您的浏览器不支持。
        </video>
      </div>
      <!-- 附件 -->
      <div class="object" v-else>
        <iframe class="Target" frameborder="1" index-render="1" scrolling="yes" height="890.15" width="1220.4" :src="TragetObj.url"></iframe>
      </div>
      <!-- 操作按钮 -->
      <div class="viewer_btn">
        <ul>
          <li @click="onClickEnlarge">
            <i class="el-icon-zoom-in"></i>
          </li>
          <li @click="onClickNarrow">
            <i class="el-icon-zoom-out"></i>
          </li>
          <li @click="onClickReturnOriginal">
            <i class="el-icon-c-scale-to-original"></i>
          </li>
          <!-- 下载 -->
          <li v-if="TragetObj.downUrl">
            <a :href="TragetObj.downUrl">
              <i class="el-icon-download"></i>
            </a>
          </li>
            <!-- <li>
              <i class="el-icon-full-screen"></i>
          </li> -->
        </ul>
      </div>
      <!--下一个 -->
      <div class="next" v-if="NumIndex < this.FilePresAll.length - 1"  @click="onClickNext">
        <i class="el-icon-arrow-right"></i>
      </div>
      <!-- 上一个 -->
      <div class="previous" v-if="NumIndex != 0" @click="onCLickPrevious">
        <i class="el-icon-arrow-left"></i>
      </div>
      <!-- 关闭按钮 -->
      <div class="close" @click="onClickClose">
        <i class="el-icon-close"></i>
      </div>
    </div>
    <div class="viewer__mask" @click.stop="onClickClose">
      <div  v-loading="loadingFlag"></div>
    </div>
  </div>
</template>

<script>
export default {
    props:['TragetPic', 'FilePreAll'],
    data(){
      return{
        EleWidth:"",
        EleHeight:"", 
        TragetObj:{}, // 目标对象
        FilePresAll:[], // 渲染数组
        NumIndex:0, // 当前渲染目标的下标
        loadingFlag:false, // 加载
      }
    },
    created(){
      this.TragetObj = this.TragetPic // 目标对象
      this.FilePresAll = this.FilePreAll // 渲染数组
    },
    mounted () {
      if(this.EleWidth == ""){
        if(this.TragetObj.format != 'jpg' && this.TragetObj.format != 'png' && this.TragetObj.format != 'JPG' && this.TragetObj.format != 'PNG' && this.TragetObj.format != 'jpeg' && this.TragetObj.format != 'tiff' && this.TragetObj.format != 'swf' && this.TragetObj.format != 'gif' && this.TragetObj.format != 'JPEG' && this.TragetObj.format != 'GIF'){
          this.loadingFlag = true
        }else{
          this.loadingFlag = false
        }
      }
      // 获取目标元素值
      let  Target = document.getElementsByClassName("Target")[0];
      this.EleWidth = Target.offsetWidth
      this.EleHeight = Target.offsetHeight
      if(this.EleWidth != ""){
        this.loadingFlag = false
      }
      // console.log(this.EleWidth)

      // 获取当前目标的下标值
      this.FilePresAll.forEach((item, index)=>{
        if(item.FileName == this.TragetObj.FileName){
          this.NumIndex = index
        }
      })
    },

    beforeUpdate () {
      if(this.TragetObj.format != 'jpg' && this.TragetObj.format != 'png' && this.TragetObj.format != 'JPG' && this.TragetObj.format != 'PNG' && this.TragetObj.format != 'jpeg' && this.TragetObj.format != 'tiff' && this.TragetObj.format != 'swf' && this.TragetObj.format != 'gif' && this.TragetObj.format != 'JPEG' && this.TragetObj.format != 'GIF'){
        this.loadingFlag = true
      }else{
        this.loadingFlag = false
      }
      this.$nextTick(()=>{
        let eleParent = document.querySelector('.object')
        // 获取目标元素值
        let Target = eleParent.children[0]
        this.EleWidth = Target.offsetWidth
        this.EleHeight = Target.offsetHeight
        // console.log(Target)
          
      })
    },
    methods:{
      // 放大功能
      onClickEnlarge(){
        let Target=document.getElementsByClassName("Target")[0];
        Target.style.height=Target.height*1.1+'px';
        Target.style.width=Target.width*1.1+'px';
      },

      // 缩小功能
      onClickNarrow(){
        let Target=document.getElementsByClassName("Target")[0];
        Target.style.height=Target.height/1.1+'px';
        Target.style.width=Target.width/1.1+'px';
      },

      // 返回原图大小
      onClickReturnOriginal(){
        let Target=document.getElementsByClassName("Target")[0];
        Target.style.height=this.EleHeight+'px';
        Target.style.width=this.EleWidth +'px';
      },

      // 点击下一个事件
      onClickNext(){
        if(this.NumIndex < this.FilePresAll.length - 1){
          this.NumIndex++
          this.TragetObj = this.FilePresAll[this.NumIndex]
        }
      },

      // 点击上一个事件
      onCLickPrevious(){
        if(this.NumIndex != 0){
          this.NumIndex--
          this.TragetObj = this.FilePresAll[this.NumIndex]
        }
      },

      // 关闭按钮
      onClickClose(){
        // 关闭视频声音
        if(this.$refs.videoref != undefined){
          this.$refs.videoref.pause()
        }
        this.$emit('Close', false)
      },

      // 拖拽图片事件
      moveImg (e) {
        e.preventDefault()
        // 获取元素
        let imgWrap = this.$refs.imgWrap
        let img = this.$refs.img
        let x = e.pageX - img.offsetLeft
        let y = e.pageY - img.offsetTop
        // 添加鼠标移动事件
        imgWrap.addEventListener('mousemove', move)
        function move (e) {
          img.style.left = e.pageX - x + 'px'
          img.style.top = e.pageY - y + 'px'
        }
        // 添加鼠标抬起事件,鼠标抬起,将事件移除
        img.addEventListener('mouseup', () => {
          imgWrap.removeEventListener('mousemove', move)
        })
        // 鼠标离开父级元素,把事件移除
        imgWrap.addEventListener('mouseout', () => {
          imgWrap.removeEventListener('mousemove', move)
        })
      },

      // 鼠标滚动缩放图片事件
      rollImg (event) {
        /* 获取当前页面的缩放比 若未设置zoom缩放比,则为默认100%,即1,原图大小 */
        let zoom = parseInt(this.$refs.img.style.zoom) || 100
        /* event.wheelDelta 获取滚轮滚动值并将滚动值叠加给缩放比zoom wheelDelta统一为±120,其中正数表示为向上滚动,负数表示向下滚动 */
        zoom += event.wheelDelta / 12
        /* 最小范围 和 最大范围 的图片缩放尺度 */
        if (zoom >= 40 && zoom < 500) {
            this.$refs.img.style.zoom = zoom + '%'
        }
        return false
      },
    }
}
</script>

<style lang="scss" scoped>
.FilePreview{
  position: fixed;
  left: 0;
  top: 0;
  z-index: 8888;
  height: 100%;
  width: 100%;
  .container{
    display: flex;
    flex-direction: column;
    align-items:center;/*由于flex-direction: column,因此align-items代表的是水平方向*/
    justify-content: center;/*由于flex-direction: column,因此justify-content代表的是垂直方向*/
    position: relative;
    left: 0;
    top: 0;
    height: 100%;
    width: 100%;
    .object{
      z-index: 10001;
      display: flex;
      flex-direction: column;
      align-items:center;/*由于flex-direction: column,因此align-items代表的是水平方向*/
      justify-content: center;/*由于flex-direction: column,因此justify-content代表的是垂直方向*/
      margin: 25px;
      .modal-img {
          position: absolute;
          left: 50%;
          top: 50%;
          transform: translate(-50%, -50%);
          max-width: 100%;
          cursor: move;
          &-wrap {
          position: relative;
          width: 960px;
          height: 560px;
          overflow: hidden;
        }
      }
    }
    .viewer_btn{
      position: absolute;
      left: 50%;
      bottom: 20px;
      z-index: 10020;
      -webkit-transform: translateX(-50%);
      transform: translateX(-50%);
      // width: 250px;
      height: 44px;
      padding: 0 23px;
      background-color: #606266;
      border-color: #fff;
      border-radius: 22px;
      ul{
        padding: 0;
        margin: 0;
        display: flex;
        justify-content: space-between;
        align-items: center;
        li{
          font-size: 30px;
          color: #fff;
          padding: 6px 10px;
          cursor: pointer;
        }
      }
    }
    .next{
      position: absolute;
      top: 50%;
      right: 15px;
      z-index: 10020;
      font-size: 30px; 
      height: 44px;
      width: 44px;
      line-height: 44px;
      text-align: center;
      background: #606266;
      color: #fff;
      border-radius: 50%;
      cursor: pointer;
    }
    .previous{
      position: absolute;
      top: 50%;
      left: 15px;
      z-index: 10020;
      font-size: 30px;
      height: 44px;
      width: 44px;
      line-height: 44px;
      text-align: center;
      background: #606266;
      color: #fff;
      border-radius: 50%;
      cursor: pointer; 
    }
    .close{
      position: absolute;
      top: 15px;
      right: 15px;
      z-index: 10020;
      font-size: 30px;
      cursor: pointer;
      background: #606266;
      border-radius: 50%;
      width: 44px;
      height: 44px;
      line-height: 44px;
      text-align: center;
    }
  }
  .viewer__mask{
    position: absolute;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.9);
    top: 0;
    left: 0;
    z-index: 8888;
    display: flex;
    flex-direction: column;
    align-items:center;/*由于flex-direction: column,因此align-items代表的是水平方向*/
    justify-content: center;/*由于flex-direction: column,因此justify-content代表的是垂直方向*/
  }
}
</style>
<style>
/* 关闭图标 */
.FilePreview .el-icon-close{   
  color: #fff;
}
</style>

在需要使用的页面引入组件:

import FilePreview from '@/pageCommon/FilePreview.vue' // 预览组件;
components: {
    FilePreview,
  },
  data(){
  	return{
  		// 预览数据
      IsPreview:false, // 控制预览弹窗字段
      timers:"", //时间戳
      FilePreAll:[], // 预览数组
      TragetPic:{}, // 当前点击的预览文件对象
  	}
  },
methods: {
	// 打开预览
    onClickOpenPreview(val){
      this.TragetPic  = { // 当前点击的文件
        FileName: val.name, // 文件名称
        name: val.name, // 文件名称(可以不传)
        id:val.guid_name, // 文件id
        format:val.extensions, // 文件格式
        url: this.previewFile + val.guid_name,  // 预览地址
        downUrl:"", // 下载地址
      } // 目标对象

      this.tableData.forEach(item =>{ // 需要预览的文件数组(可以传空数组就是单张预览)
        let obj = {
          FileName: item.name,
          name: item.name,
          id:item.guid_name,
          format:item.extensions,
          url: this.previewFile + item.guid_name,
          downUrl:"",
        }
        this.FilePreAll.push(obj)
      })

     
      this.IsPreview = true // 打开预览弹窗
      this.timers = new Date().getTime() // 刷新预览地址
    },
	// 关闭预览
    onClickClosePreview(val){
      this.IsPreview = val  // 由组件内部传入的关闭数据赋值关闭
    },
}

在template中使用:

<!-- 预览 -->
    <div class="preview" v-if="IsPreview">
      <file-preview :key="timers" :TragetPic="TragetPic" :FilePreAll="FilePreAll" @Close="onClickClosePreview"></file-preview>
    </div>

最后看效果图:
图片预览:
在这里插入图片描述
文件预览:
在这里插入图片描述
在这里插入图片描述

虽然封装的不是很好,文件预览主要是使用了iframe,同时还支持视频的预览,先将就用着,后续再进行更好的优化,更简易化的使用,目前还是有些复杂。不懂的可以评论咨询哈,谢谢支持;

最后

以上就是神勇钢笔为你收集整理的根据element改造的文件预览组件:支持图片、doc、xlsx、ppt、PDF、视频等文件预览的全部内容,希望文章能够帮你解决根据element改造的文件预览组件:支持图片、doc、xlsx、ppt、PDF、视频等文件预览所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部