最近在公司遇到了很多模块需要实现弹窗预览文件的需求,所以我决定在项目中统一封装一个组件来实现这一功能,在这里记录一下具体的实现。
我们知道只要在浏览器中访问文件的地址就可以预览该文件,所以我决定使用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)
效果: