feat: vue2版本示例,详细demo
This commit is contained in:
parent
01edf4c5a0
commit
14bc1951d3
180
README.md
180
README.md
@ -1,24 +1,172 @@
|
||||
# file-view-demo-vue2
|
||||
# FileViewer 项目Vue2 demo
|
||||
|
||||
本demo基于vue-cli+js+vue2.x构建,如果您需要vue3版本的demo,请前往main分支。
|
||||
|
||||
**适用于Vue2 + Webpack,本集成方法要求最低Webpack版本为5,也就是Vue Cli Service 5.0.0以上,当然,iframe集成没有任何限制**
|
||||
|
||||
> 注意,为了版本稳定性,在iframe集成的场景下,无论是vue2版本还是vue3版本,都建议使用file-viewer3以获得最佳性能。
|
||||
|
||||
|
||||
## 方式一:iframe集成(推荐)
|
||||
|
||||
iframe集成是我们最推荐的集成方式,可以跳过所有的坑,为您的项目快速集成文件预览能力。
|
||||
|
||||
|
||||
### 源码准备
|
||||
下载我们的最新版本的file-viewer源码,然后执行`npm build build`,或者`yarn build`。
|
||||
|
||||
### 构建产物集成
|
||||
然后将构建后的dist目录拷贝到您项目的public目录下。当然也可以放置到任何项目中。本demo只是演示。
|
||||
|
||||
如果您在公网,建议您使用我们的cdn:
|
||||
|
||||
https://viewer.flyfish.dev
|
||||
|
||||
以获得高效的访问。
|
||||
|
||||
如果您在内网,可以完全参照本demo进行实施。
|
||||
|
||||
### 添加iframe标签
|
||||
您可以实现一个组件,内部包含一个`<iframe>`标签,接下来您有两种方法进行文件切换。
|
||||
|
||||
1. **使用url控制切换(推荐)**
|
||||
|
||||
这种方式是最便捷的实现方式,适合有文件链接的方案。如果你的文件是**流式传输**或者需要用于上传体验,则不适合该方案。
|
||||
|
||||
2. **使用postMessage发送文件数据**
|
||||
|
||||
这种方式适合本地上传或者后端返回流式二进制数据。
|
||||
|
||||
示例的`IframeViewer.vue`组件实现如下,该组件同时支持两种文件控制方式,您可以直接集成:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<iframe title="文档预览" ref="frame" :src="src" class="iframe-viewer"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
// 查看器的源,当前示例为本源,指定为location.origin即可
|
||||
const viewerOrigin = location.origin;
|
||||
|
||||
// iframe路径指向构建产物,这里是/,因为放在了public下面
|
||||
// 如果使用cdn,请使用https://viewer.flyfish.dev
|
||||
const source = '/dist/index.html'
|
||||
|
||||
export default {
|
||||
name: 'IframeViewer',
|
||||
props: {
|
||||
url: String,
|
||||
file: File,
|
||||
name: String,
|
||||
},
|
||||
mounted() {
|
||||
this.sendFileData();
|
||||
},
|
||||
computed: {
|
||||
// 构建完整url
|
||||
src() {
|
||||
// 文件名称,建议传递,提高体验性
|
||||
const name = this.name || '';
|
||||
if (this.url) {
|
||||
// 直接拼接url
|
||||
return `${source}?url=${encodeURIComponent(this.url)}&name=${encodeURIComponent(name)}`
|
||||
} else if (this.file) {
|
||||
// 直接拼接来源origin
|
||||
return `${source}?from=${encodeURIComponent(viewerOrigin)}&name=${encodeURIComponent(name)}`
|
||||
} else {
|
||||
return source;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 发送文件数据
|
||||
sendFileData() {
|
||||
this.nextTick(() => {
|
||||
// iframe引用
|
||||
const viewer = this.$refs.frame;
|
||||
if (!viewer || !this.file) return;
|
||||
viewer.onload = () => viewer.contentWindow?.postMessage(this.file, viewerOrigin);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.iframe-viewer {
|
||||
height: calc(100vh - 2px);
|
||||
width: 100%;
|
||||
border: 0
|
||||
}
|
||||
</style>
|
||||
|
||||
## Project setup
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
yarn serve
|
||||
|
||||
|
||||
## 方式二: 使用仓库依赖集成
|
||||
|
||||
该方案适合有定制化需求,或者想要控制显示样式或者灵活控制渲染的开发需求。
|
||||
|
||||
为了您能够快速集成本项目,我们在中央仓库发布了我们的NPM包。具体地址如下:
|
||||
|
||||
- [Vue2版本](https://www.npmjs.com/package/@flyfish-group/file-viewer)
|
||||
|
||||
- [Vue3版本](https://www.npmjs.com/package/@flyfish-group/file-viewer3)
|
||||
|
||||
您可以根据项目架构快速选用组件。
|
||||
|
||||
以下是示例代码:
|
||||
|
||||
`main.js`
|
||||
|
||||
```javascript
|
||||
import Vue from 'vue'
|
||||
import FileViewer from '@flyfish-group/file-viewer'
|
||||
|
||||
// 导入样式
|
||||
import '@flyfish-group/file-viewer/dist/style.css'
|
||||
|
||||
Vue.use(FileViewer);
|
||||
|
||||
new Vue({
|
||||
render: h => h(App),
|
||||
}).$mount('#app')
|
||||
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
yarn build
|
||||
`InnerViewer.vue`
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class='simple-view'>
|
||||
<file-viewer :url="url" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'InnerViewer',
|
||||
props: {
|
||||
url: String,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.simple-view {
|
||||
width: 100%;
|
||||
height: calc(100vh - 2px);
|
||||
}
|
||||
</style>
|
||||
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
yarn lint
|
||||
```
|
||||
需要注意的是,内置组件`file-viewer`支持使用data的方式传入文件的二进制数据,您可以自行从服务器拉取集成。以下是组件API。
|
||||
|
||||
| 属性名 | 类型 | 示例 | 属性描述 |
|
||||
| ------ | --------------------------- | ---------------------------- | --------------------------------------------------------- |
|
||||
| file | File \| Blob \| ArrayBuffer | new Blob(...) | 支持文件、二进制blob和arraybuffer数组缓存 |
|
||||
| url | String | "https://flyfish.dev/1.docx" | 支持任意服务器文件url,需要支持跨域访问,即存在cors响应头 |
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
|
@ -8,6 +8,7 @@
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@flyfish-group/file-viewer": "^1.0.4",
|
||||
"core-js": "^3.8.3",
|
||||
"vue": "^2.6.14"
|
||||
},
|
||||
|
BIN
public/666.pdf
Normal file
BIN
public/666.pdf
Normal file
Binary file not shown.
BIN
public/888.pdf
Normal file
BIN
public/888.pdf
Normal file
Binary file not shown.
9
public/dist/assets/ImageViewer-b2513ebd.css
vendored
Normal file
9
public/dist/assets/ImageViewer-b2513ebd.css
vendored
Normal file
File diff suppressed because one or more lines are too long
9
public/dist/assets/ImageViewer-ed99ad9c.js
vendored
Normal file
9
public/dist/assets/ImageViewer-ed99ad9c.js
vendored
Normal file
File diff suppressed because one or more lines are too long
45
public/dist/assets/MarkdownViewer-52070412.js
vendored
Normal file
45
public/dist/assets/MarkdownViewer-52070412.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/dist/assets/MarkdownViewer-86c94709.css
vendored
Normal file
1
public/dist/assets/MarkdownViewer-86c94709.css
vendored
Normal file
File diff suppressed because one or more lines are too long
15
public/dist/assets/PdfView-3f48c404.js
vendored
Normal file
15
public/dist/assets/PdfView-3f48c404.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/dist/assets/PdfView-89e0fbd8.css
vendored
Normal file
1
public/dist/assets/PdfView-89e0fbd8.css
vendored
Normal file
File diff suppressed because one or more lines are too long
47
public/dist/assets/PptxRender-5a3debe6.js
vendored
Normal file
47
public/dist/assets/PptxRender-5a3debe6.js
vendored
Normal file
File diff suppressed because one or more lines are too long
9
public/dist/assets/PptxRender-846be824.css
vendored
Normal file
9
public/dist/assets/PptxRender-846be824.css
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
.slide{position:relative;border:1px solid #333;border-radius:10px;overflow:hidden;margin-bottom:50px;margin-left:auto;margin-right:auto;z-index:100}.slide div.block{position:absolute;top:0;left:0;width:100%;line-height:1}.slide div.content,.slide div.diagram-content{display:flex;flex-direction:column}.slide div.content-rtl{display:flex;flex-direction:column;direction:rtl}.slide .pregraph-rtl{direction:rtl}.slide .pregraph-ltr{direction:ltr}.slide .pregraph-inherit{direction:inherit}.slide .slide-prgrph{width:100%}.slide .line-break-br:before{content:"\a";white-space:pre}.slide div.v-up{justify-content:flex-start}.slide div.v-mid{justify-content:center}.slide div.v-down{justify-content:flex-end}.slide div.h-left{justify-content:flex-start;align-items:flex-start;text-align:left}.slide div.h-left-rtl{justify-content:flex-end;align-items:flex-end;text-align:left}.slide div.h-mid{justify-content:center;align-items:center;text-align:center}.slide div.h-right{justify-content:flex-end;align-items:flex-end;text-align:right}.slide div.h-right-rtl{justify-content:flex-start;align-items:flex-start;text-align:right}.slide div.h-just,.slide div.h-dist{text-align:justify}.slide div.up-left{justify-content:flex-start;align-items:flex-start;text-align:left}.slide div.up-center{justify-content:flex-start;align-items:center}.slide div.up-right{justify-content:flex-start;align-items:flex-end}.slide div.center-left{justify-content:center;align-items:flex-start;text-align:left}.slide div.center-center{justify-content:center;align-items:center}.slide div.center-right{justify-content:center;align-items:flex-end}.slide div.down-left{justify-content:flex-end;align-items:flex-start;text-align:left}.slide div.down-center{justify-content:flex-end;align-items:center}.slide div.down-right{justify-content:flex-end;align-items:flex-end}.slide li.slide{margin:10px 0;font-size:18px}.slide table{position:absolute}.slide svg.drawing{position:absolute;overflow:visible}/*!
|
||||
* Copyright (c) 2017 ~ present NAVER Corp.
|
||||
* billboard.js project is licensed under the MIT license
|
||||
*
|
||||
* billboard.js, JavaScript chart library
|
||||
* https://naver.github.io/billboard.js/
|
||||
*
|
||||
* @version 3.10.3
|
||||
*/.bb-color-pattern{background-image:url(#00c73c;#fa7171;#2ad0ff;#7294ce;#e3e448;#cc7e6e;#fb6ccf;#c98dff;#4aea99;#bbbbbb;)}.bb svg{font-size:12px;font-family:sans-serif,Arial,nanumgothic,Dotum;line-height:1}.bb path,.bb line{fill:none;stroke:#c4c4c4}.bb text,.bb .bb-button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;fill:#555;font-size:11px}.bb-legend-item-title,.bb-xgrid-focus,.bb-ygrid-focus,.bb-ygrid{shape-rendering:crispEdges}.bb-chart-arcs .bb-needle{fill:#000}.bb-axis{shape-rendering:crispEdges}.bb-axis-y text,.bb-axis-y2 text{fill:#737373}.bb-event-rects{fill-opacity:1!important}.bb-event-rects .bb-event-rect{fill:transparent}.bb-event-rects .bb-event-rect._active_{fill:#27c9030d}.tick._active_ text{fill:#00c83c!important}.bb-grid{pointer-events:none}.bb-grid line{stroke:#f1f1f1}.bb-xgrid-focus line,.bb-ygrid-focus line{stroke:#ddd}.bb-text.bb-empty{fill:#767676}.bb-line{stroke-width:1px}.bb-circle._expanded_{fill:#fff!important;stroke-width:2px;stroke:red}rect.bb-circle._expanded_,use.bb-circle._expanded_{stroke-width:1px}.bb-selected-circle{fill:#fff;stroke-width:2px}.bb-bar{stroke-width:0}.bb-bar._expanded_{fill-opacity:.75}.bb-candlestick{stroke-width:1px}.bb-candlestick._expanded_{fill-opacity:.75}.bb-target.bb-focused,.bb-circles.bb-focused{opacity:1}.bb-target.bb-focused path.bb-line,.bb-target.bb-focused path.bb-step,.bb-circles.bb-focused path.bb-line,.bb-circles.bb-focused path.bb-step{stroke-width:2px}.bb-target.bb-defocused,.bb-circles.bb-defocused{opacity:.3!important}.bb-target.bb-defocused .text-overlapping,.bb-circles.bb-defocused .text-overlapping{opacity:.05!important}.bb-region rect{fill:#4682b4;fill-opacity:.1}.bb-region.selected rect{fill:#27c903}.bb-zoom-brush,.bb-brush .extent{fill-opacity:.1}.bb-legend-item{-webkit-user-select:none;user-select:none}.bb-legend-item-hidden{opacity:.15}.bb-legend-background{opacity:.75;fill:#fff;stroke:#d3d3d3;stroke-width:1}.bb-title{font-size:14px}.bb-chart-treemaps rect{stroke:#fff;stroke-width:1px}.bb-tooltip-container{z-index:10;font-family:sans-serif,Arial,nanumgothic,Dotum;-webkit-user-select:none;user-select:none}.bb-tooltip{border-collapse:separate;border-spacing:0;empty-cells:show;border:1px solid #999;background-color:#fff;text-align:left;font-size:11px;white-space:nowrap}.bb-tooltip th{font-size:12px;padding:4px 8px;text-align:left;border-bottom:solid 1px #eee}.bb-tooltip td{padding:4px 6px;background-color:#fff}.bb-tooltip td:first-child{padding-left:8px}.bb-tooltip td:last-child{padding-right:8px}.bb-tooltip td>span,.bb-tooltip td>svg{display:inline-block;width:10px;height:10px;margin-right:6px;border-radius:5px;vertical-align:middle}.bb-tooltip td.value{border-left:1px solid transparent}.bb-tooltip .bb-tooltip-title{display:inline-block;color:#aaa;line-height:20px}.bb-tooltip .bb-tooltip-detail table{border-collapse:collapse;border-spacing:0}.bb-tooltip .bb-tooltip-detail .bb-tooltip-name,.bb-tooltip .bb-tooltip-detail .bb-tooltip-value{font-size:11px;line-height:13px;padding:4px 0 3px;color:#444;text-align:left;font-weight:400}.bb-tooltip .bb-tooltip-detail .bb-tooltip-value{padding-left:5px;font-weight:800;font-size:12px}.bb-area{stroke-width:0;opacity:.2}.bb-chart-arcs-title{dominant-baseline:middle;font-size:1.3em}text.bb-chart-arcs-gauge-title{dominant-baseline:middle;font-size:2.7em}.bb-chart-arcs .bb-chart-arcs-background{fill:#e0e0e0;stroke:none}.bb-chart-arcs .bb-chart-arcs-gauge-unit{fill:#000;font-size:16px}.bb-chart-arcs .bb-chart-arcs-gauge-min,.bb-chart-arcs .bb-chart-arcs-gauge-max{fill:#777}.bb-chart-arcs .bb-chart-arcs-title{font-size:16px!important;fill:#000;font-weight:600}.bb-chart-arcs path.empty{fill:#eaeaea;stroke-width:0}.bb-chart-arcs .bb-levels circle{fill:none;stroke:#848282;stroke-width:.5px}.bb-chart-arcs .bb-levels text{fill:#848282}.bb-chart-arc .bb-gauge-value{fill:#000}.bb-chart-arc path{stroke:#fff}.bb-chart-arc rect{stroke:#fff;stroke-width:1}.bb-chart-arc text{fill:#fff;font-size:13px}.bb-chart-radars .bb-levels polygon{fill:none;stroke:#848282;stroke-width:.5px}.bb-chart-radars .bb-levels text{fill:#848282}.bb-chart-radars .bb-axis line{stroke:#848282;stroke-width:.5px}.bb-chart-radars .bb-axis text{font-size:1.15em;cursor:default}.bb-chart-radars .bb-shapes polygon{fill-opacity:.2;stroke-width:1px}.bb-button{position:absolute;top:10px;right:10px}.bb-button .bb-zoom-reset{border:solid 1px #ccc;background-color:#fff;padding:5px;border-radius:5px;cursor:pointer}.pptx-wrapper[data-v-1b0d57cb]{max-width:100%;margin:0 auto}
|
102
public/dist/assets/XlsxTable-0a398d95.js
vendored
Normal file
102
public/dist/assets/XlsxTable-0a398d95.js
vendored
Normal file
File diff suppressed because one or more lines are too long
41
public/dist/assets/XlsxTable-5454e362.css
vendored
Normal file
41
public/dist/assets/XlsxTable-5454e362.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/dist/assets/_commonjs-dynamic-modules-302442b1.js
vendored
Normal file
1
public/dist/assets/_commonjs-dynamic-modules-302442b1.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
function r(o){throw new Error('Could not dynamically require "'+o+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}export{r as c};
|
27
public/dist/assets/docx-preview-1cf76835.js
vendored
Normal file
27
public/dist/assets/docx-preview-1cf76835.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/dist/assets/index-b9d6ea81.css
vendored
Normal file
1
public/dist/assets/index-b9d6ea81.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.banner[data-v-3f8fdb10]{overflow:auto;text-align:center;background-color:#12b6ff;color:#fff}.viewport[data-v-3f8fdb10]{border:1px solid #ccc;margin:5px;width:calc(100% - 12px);height:calc(100vh - 73px)}.hidden .banner[data-v-3f8fdb10]{display:none}.hidden .viewport[data-v-3f8fdb10]{height:100vh!important}.hidden .well[data-v-3f8fdb10]{height:calc(100vh - 12px)}.overlay[data-v-3f8fdb10]{position:absolute;transition:all;z-index:1000;opacity:.4;top:50px;left:112px;padding:20px;border-radius:5px;background:white;border:1px solid silver}.overlay[data-v-3f8fdb10]:hover{opacity:1}.file-select[data-v-3f8fdb10]{position:absolute;left:5%;line-height:35px;margin-left:20px}.banner a[data-v-3f8fdb10]{color:#fff;text-decoration:none}.banner h1[data-v-3f8fdb10]{font-size:20px;line-height:2;margin:.5em 0}.file-select button[data-v-3f8fdb10]{background:#fafafa}.overlay button[data-v-3f8fdb10]{background:#12b6ff;color:#fff}button[data-v-3f8fdb10]{outline:none;border-radius:20px;border:1px solid #e3e3e3;line-height:19px;padding:5px 12px;cursor:pointer}.overlay input[type=text][data-v-3f8fdb10]{line-height:19px;height:30px;width:300px;outline:none;border:1px solid silver;border-radius:6px;margin-right:10px}.overlay input[type=file][data-v-3f8fdb10]{position:absolute;opacity:0;width:100%;height:100%;left:0;top:0;z-index:2;cursor:pointer}.upload-cover[data-v-3f8fdb10]{z-index:1;pointer-events:none;color:#000}.messages .warning[data-v-3f8fdb10]{color:#c60}html{overflow-y:scroll;font-family:helvetica,arial,sans-serif}body{margin:0;padding:0}#app{width:100%;height:100%}#app{width:100%;font-weight:400}.code-area[data-v-3be501eb]{display:block;margin:0 auto;font-size:12px;width:1000px;min-height:500px;background:#1f1f1f;word-break:break-word;white-space:break-spaces;color:#5af117}.file-viewer[data-v-4732f9f2]{position:relative;width:100%;height:100%}.content[data-v-4732f9f2]{display:block;background-color:#f2f2f2;width:100%;height:100%;overflow:auto}.loading[data-v-4732f9f2]{text-align:center;padding-top:50px}.name[data-v-4732f9f2]{position:absolute;bottom:0;left:0;width:100%;padding:13px 0;font-size:20px;text-shadow:2px 2px #616161;pointer-events:none;color:#fff;background:rgba(31,31,31,.22);text-align:center;z-index:10000}.file-render{width:100%;height:100%}
|
27
public/dist/assets/index-be50c070.js
vendored
Normal file
27
public/dist/assets/index-be50c070.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
public/dist/assets/loading-43b144a3.gif
vendored
Normal file
BIN
public/dist/assets/loading-43b144a3.gif
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
58
public/dist/assets/pdf.worker-2ce04d0b.js
vendored
Normal file
58
public/dist/assets/pdf.worker-2ce04d0b.js
vendored
Normal file
File diff suppressed because one or more lines are too long
21
public/dist/assets/pptx.worker-a9caaa79.js
vendored
Normal file
21
public/dist/assets/pptx.worker-a9caaa79.js
vendored
Normal file
File diff suppressed because one or more lines are too long
38
public/dist/assets/sheet.worker-d79186a2.js
vendored
Normal file
38
public/dist/assets/sheet.worker-d79186a2.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/dist/assets/worker-ref-b3abaee8.js
vendored
Normal file
1
public/dist/assets/worker-ref-b3abaee8.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
var s=Object.defineProperty;var t=(e,r,o)=>r in e?s(e,r,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[r]=o;var l=(e,r,o)=>(t(e,typeof r!="symbol"?r+"":r,o),o);const n="/node_modules/@flyfish-group/file-viewer3/dist/worker/";class u{constructor(r){l(this,"worker",null);this.worker=r}defaults(r){return this.worker||r()}}function i(e,r=!1){let o=null;return`${n}${e}`,new u(o)}export{i as r};
|
BIN
public/dist/assets/xlsx-08add3c8.png
vendored
Normal file
BIN
public/dist/assets/xlsx-08add3c8.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
62
public/dist/assets/xlsx.worker-9278a0aa.js
vendored
Normal file
62
public/dist/assets/xlsx.worker-9278a0aa.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
public/dist/favicon.ico
vendored
Normal file
BIN
public/dist/favicon.ico
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
15
public/dist/index.html
vendored
Normal file
15
public/dist/index.html
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="./favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>File Viewer在线预览器vue3.0版本</title>
|
||||
<script type="module" crossorigin src="./assets/index-be50c070.js"></script>
|
||||
<link rel="stylesheet" href="./assets/index-b9d6ea81.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
BIN
public/excel.xlsx
Normal file
BIN
public/excel.xlsx
Normal file
Binary file not shown.
77
src/App.vue
77
src/App.vue
@ -1,28 +1,79 @@
|
||||
|
||||
<template>
|
||||
<div id="app">
|
||||
<img alt="Vue logo" src="./assets/logo.png">
|
||||
<HelloWorld msg="Welcome to Your Vue.js App"/>
|
||||
<header>
|
||||
<div class="tool-bar">
|
||||
<div>
|
||||
<h3>选择预览模式</h3>
|
||||
<input type="radio" name="mode" value="inner" v-model="mode" />内置访问
|
||||
<input type="radio" name="mode" value="embedded" v-model="mode" />iframe访问
|
||||
</div>
|
||||
<div>
|
||||
<h3>选择文档</h3>
|
||||
<select v-model="url">
|
||||
<optgroup label="excel">
|
||||
<option :value="excel">常规excel</option>
|
||||
</optgroup>
|
||||
<optgroup label="pdf">
|
||||
<option :value="pdf1">复杂pdf</option>
|
||||
<option :value="pdf2">简单pdf</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<InnerViewer v-if="mode === 'inner'" :url="url" />
|
||||
<IframeViewer v-else-if="mode === 'embedded'" :url="url" />
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HelloWorld from './components/HelloWorld.vue'
|
||||
import InnerViewer from './components/InnerViewer'
|
||||
import IframeViewer from "./components/IframeViewer";
|
||||
|
||||
// 测试文件,这些文件实际情况可能是其他服务器链接
|
||||
const excel = 'excel.xlsx';
|
||||
const pdf1 = '666.pdf';
|
||||
const pdf2 = '888.pdf';
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
data() {
|
||||
return {
|
||||
url: excel,
|
||||
mode: 'inner',
|
||||
excel,
|
||||
pdf1,
|
||||
pdf2,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
HelloWorld
|
||||
InnerViewer,
|
||||
IframeViewer
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
margin-top: 60px;
|
||||
<style scoped>
|
||||
header {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.tool-bar {
|
||||
background-color: hsla(160, 100%, 37%, 0.2);
|
||||
width: 230px;
|
||||
height: 100vh;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
header {
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
header .wrapper {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
33
src/assets/main.css
Normal file
33
src/assets/main.css
Normal file
@ -0,0 +1,33 @@
|
||||
#app {
|
||||
width: 100%;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
a,
|
||||
.green {
|
||||
text-decoration: none;
|
||||
color: hsla(160, 100%, 37%, 1);
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
a:hover {
|
||||
background-color: hsla(160, 100%, 37%, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
body {
|
||||
display: flex;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
#app {
|
||||
display: block;
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
For a guide and recipes on how to configure / customize this project,<br>
|
||||
check out the
|
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
||||
</p>
|
||||
<h3>Installed CLI Plugins</h3>
|
||||
<ul>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
||||
</ul>
|
||||
<h3>Essential Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
||||
</ul>
|
||||
<h3>Ecosystem</h3>
|
||||
<ul>
|
||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
props: {
|
||||
msg: String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
60
src/components/IframeViewer.vue
Normal file
60
src/components/IframeViewer.vue
Normal file
@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<iframe title="文档预览" ref="frame" :src="src" class="iframe-viewer"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
// 查看器的源,当前示例为本源,指定为location.origin即可
|
||||
const viewerOrigin = location.origin;
|
||||
|
||||
// iframe路径指向构建产物,这里是/,因为放在了public下面
|
||||
// 如果使用cdn,请使用https://viewer.flyfish.dev
|
||||
const source = '/dist/index.html'
|
||||
|
||||
export default {
|
||||
name: 'IframeViewer',
|
||||
props: {
|
||||
url: String,
|
||||
file: File,
|
||||
name: String,
|
||||
},
|
||||
mounted() {
|
||||
this.sendFileData();
|
||||
},
|
||||
computed: {
|
||||
// 构建完整url
|
||||
src() {
|
||||
// 文件名称,建议传递,提高体验性
|
||||
const name = this.name || '';
|
||||
if (this.url) {
|
||||
// 直接拼接url
|
||||
return `${source}?url=${encodeURIComponent(this.url)}&name=${encodeURIComponent(name)}`
|
||||
} else if (this.file) {
|
||||
// 直接拼接来源origin
|
||||
return `${source}?from=${encodeURIComponent(viewerOrigin)}&name=${encodeURIComponent(name)}`
|
||||
} else {
|
||||
return source;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 发送文件数据
|
||||
sendFileData() {
|
||||
this.nextTick(() => {
|
||||
// iframe引用
|
||||
const viewer = this.$refs.frame;
|
||||
if (!viewer || !this.file) return;
|
||||
viewer.onload = () => viewer.contentWindow?.postMessage(this.file, viewerOrigin);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.iframe-viewer {
|
||||
height: calc(100vh - 2px);
|
||||
width: 100%;
|
||||
border: 0
|
||||
}
|
||||
</style>
|
21
src/components/InnerViewer.vue
Normal file
21
src/components/InnerViewer.vue
Normal file
@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<div class='simple-view'>
|
||||
<file-viewer :url="url" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'InnerViewer',
|
||||
props: {
|
||||
url: String,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.simple-view {
|
||||
width: 100%;
|
||||
height: calc(100vh - 2px);
|
||||
}
|
||||
</style>
|
@ -1,8 +1,14 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import FileViewer from '@flyfish-group/file-viewer'
|
||||
|
||||
// 导入样式
|
||||
import '@flyfish-group/file-viewer/dist/style.css'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Vue.use(FileViewer);
|
||||
|
||||
new Vue({
|
||||
render: h => h(App),
|
||||
}).$mount('#app')
|
||||
|
@ -1,4 +1,7 @@
|
||||
const { defineConfig } = require('@vue/cli-service')
|
||||
module.exports = defineConfig({
|
||||
// 我们使用根节点,如果使用其他子目录,请设置具体的路径映射
|
||||
publicPath: '/',
|
||||
// 默认转换依赖
|
||||
transpileDependencies: true
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user