vue自定义插件结合iframe封装组件及函数实现弹窗预览文件功能

最近在公司遇到了很多模块需要实现弹窗预览文件的需求,所以我决定在项目中统一封装一个组件来实现这一功能,在这里记录一下具体的实现。

我们知道只要在浏览器中访问文件的地址就可以预览该文件,所以我决定使用iframe嵌入访问文件地址的网页来实现预览功能,再将iframe放在弹窗组件中,就实现了弹窗打开预览文件的功能。然后就是要实现调用一个api传入url就能调用这个组件实现文件预览的功能,这里最好是自定义一个vue插件,然后在插件的js文件中定义一个函数来接收url并调用组件,再将这个函数挂载到vue的实例对象prototype上,这样就完成了封装文件预览这一功能,在其他组件中就可以调用this.$方法名()来调用文件预览这一功能。

接下来看一下每一步骤具体的代码实现:

1、文件预览弹窗组件

<template>
  <!-- 公司组件库的弹窗组件,和element的弹窗组件用法一样 -->
  <sc-tf-dialog-base
    ref="scTfDialog"
    class="prod-dialog"
    :cancelBtnText="'关闭'"
    dialog-name="文件预览"
    :fullscreen="magnify"
    :height="magnify ? '90vh' : '550px'"
    :show-confirm-button="false"
    @beforeClose="closeDialog"
  >
    <template #title>
      <div class="file-title">
        <div>文件预览</div>
        <div>
          <sp-icon
            :type="magnify ? 'restore' : 'magnify'"
            color="#8998AC"
            style="margin-right: 10px"
            @click.native="magnify = !magnify"
            fontSize="25"
          ></sp-icon>
        </div>
      </div>
    </template>
    <!-- iframe嵌入预览文件的网页 -->
    <iframe class="prism-player" :src="origin + url" width="100%" height="100%"></iframe>
  </sc-tf-dialog-base>
</template>
<script>
export default {
      
      
  data() {
      
      
    return {
      
      
      magnify: false
    }
  },
  props: {
      
      
    config: {
      
      
      type: Object,
      default: () => ({
      
      })
    },
    // 接收传入的文件地址
    url: {
      
      
      type: String,
      default: ''
    },
    // 这里我们项目提供了一个接口传入文件的url后会通过nginx代理到另一个预览的组件中,能提供功能更为全面的预览功能(业务需求,可以忽略,直接将文件url传入iframe也能实现基础的预览功能)
    origin: {
      
      
      type: String,
      default:
        process.env.NODE_ENV === 'development'
          ? `${ 
        process.env.VUE_APP_PREVIWE_URL}/onlinePreview?url=`
          : `http://${ 
        window.location.hostname}:${ 
        process.env.VUE_APP_PREVIWE_URLNEW}/onlinePreview?url=`
    },
    // 接收关闭弹窗的方法
    close: {
      
      
      type: Function
    }
  },
  components: {
      
      },
  created() {
      
      
    this.$nextTick(() => {
      
      
      console.log(this.url)
      this.$refs['scTfDialog'].showDialog()
    })
  },
  methods: {
      
      
    //关闭弹窗
    closeDialog() {
      
      
      if (this.close) {
      
      
        this.close()
      }
    }
  }
}
</script>
<style lang="stylus" scoped>
// 省略样式代码
</style>

2、自定义vue插件挂载调用文件预览功能的方法

// 引入弹窗组件
import filePreviewPopup from './FilePreviewPopup.vue'
import {
    
     Base64 } from 'js-base64'
import Vue from 'vue'
// 将组件添加到dom中以实现打开弹窗的效果
const handleVedioBox = (url) => {
    
    
  // 注册组件
  const FileViewerConstructor = Vue.extend(filePreviewPopup)
  const instance = new FileViewerConstructor({
    
    
    url: url
  })
  // Base64加密传入弹窗组件的url(由于业务需求需要将文件url作为参数传入另一个链接地址中,所以这里需要加密一下)
  instance.url = encodeURIComponent(Base64.encode(url))
  // 将组件添加到dom中--打开弹窗
  document.body.appendChild(instance.$mount().$el)
  // 定义关闭弹窗的方法
  instance.close = () => {
    
    
    document.body.removeChild(instance.$mount().$el)
  }
}
// 定义插件的install方法(入口函数),在Vue.use()后会进入该文件自动执行install方法
const install = function (Vue) {
    
    
  // 挂载函数
  Vue.prototype.$filePreviewPopup = handleVedioBox
}
export default {
    
     install }

3、注册插件

import Vue from 'vue'
import FilePreviewPopup from './FilePreviewPopup/index'
// 注册插件,会直接进入插件js文件并执行install方法
Vue.use(FilePreviewPopup)

4、其他组件中传入文件url即可打开弹窗组件预览文件

this.$filePreviewPopup(url)

效果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/minusing/article/details/138127634