npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

file-preview-vue2-1

v1.0.0

Published

Vue 2 file preview component (txt / docx / pdf / pptx) with keyword highlight

Readme

FilePreview 文件预览组件(Vue 2)

基于 Vue 2(建议 2.7.x,以使用 Composition API)的文件预览组件,支持多种文件格式的在线预览,包括文本文件、Word 文档、PDF 文件和 PowerPoint 演示文稿。

功能特性

  • 📄 多格式支持:自动识别并预览 TXT、DOC/DOCX、PDF、PPT/PPTX 等文件格式
  • 🔍 文本高亮:支持关键词高亮显示,可自定义高亮样式
  • 📑 分页导航:支持 PDF 和 PPT 文件的页码跳转和定位
  • 性能优化:大文件下载时显示实时下载速度,提供加载状态反馈
  • 🎨 响应式设计:可根据容器宽度更新内部布局(见 triggerFullFill
  • ⚠️ 错误处理:完善的错误处理机制,文件加载失败时显示友好提示

支持的文件格式

| 文件类型 | 扩展名 | 说明 | |---------|--------|------| | 文本文件 | .txt | 纯文本文件预览 | | Word 文档 | .doc, .docx | 使用 docx-preview 渲染 | | PDF 文件 | .pdf | 使用 vue-pdf-embed(Vue 2 构建入口)渲染 | | PowerPoint | .ppt, .pptx | 使用 pptx-preview 渲染 |

环境要求

  • Vue^2.7.0(推荐 2.7.16)
  • Element UI^2.15.x(组件内使用 Loading,需在工程中 Vue.use(ElementUI)
  • 构建工具需能编译 .vueLess(如 Webpack + vue-loader + less-loader,或 Vite + vite-plugin-vue2

安装依赖

方式一:使用发布的 npm 包(.tgz

file-preview 目录执行 npm pack(或 npm run pack),会生成形如 core-pilot-file-preview-vue2-<version>.tgz 的文件(<version> 与当前 package.json 中一致),在业务项目中安装:

npm install ./path/to/core-pilot-file-preview-vue2-1.0.0.tgz

包名:@core-pilot/file-preview-vue2package.jsonmainindex.vue(源码包,非预编译 dist)。

若打包工具无法通过包名解析到 .vue,可改为显式路径:

import FilePreview from '@core-pilot/file-preview-vue2/index.vue';

方式二:拷贝源码

将组件目录拷入工程(如 src/components/file-preview),自行保证依赖一致。

Peer 依赖(建议在业务项目中安装)

安装 .tgz 时,npm 会按子包 package.jsondependencies 一并安装传递依赖;为避免多份 vue、并便于锁定版本,业务侧仍建议显式安装:

npm install vue@^2.7 element-ui docx-preview vue-pdf-embed pptx-preview mark.js lodash

docx-preview / vue-pdf-embed 还会用到 jszippdfjs-dist 等,一般由上述包自动带上;若构建报缺模块,再手动安装即可。

PDF 子组件固定从 vue-pdf-embed/dist/vue2-pdf-embed.js 引入。请安装仍提供该文件的 vue-pdf-embed 版本;独立子包 @core-pilot/file-preview-vue2package.json 声明为 ^1.2.1。若在 monorepo 中被解析到更高主版本,以实际包内是否包含上述路径为准。

全局注册 Element UI(必须)

组件依赖 Element UI 的 Loading,请在入口中:

import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);

样式:index.vue 已引入 ./style/index.less,请确保构建链能处理 Less。

基础用法

以下示例使用 Vue 2.7setup + defineComponent(与 Vue 3 写法接近)。若项目为纯 Options API,见下文「Options API 示例」。

<template>
  <file-preview
    :url="fileUrl"
    :highlight="keywords"
    :page="currentPage"
    :show-highlight="true"
  />
</template>

<script>
import { defineComponent, ref } from 'vue';
import FilePreview from '@core-pilot/file-preview-vue2';

export default defineComponent({
  name: 'DemoPage',
  components: {
    FilePreview,
  },
  setup() {
    const fileUrl = ref('https://example.com/document.pdf');
    const keywords = ref(['关键词1', '关键词2']);
    const currentPage = ref(1);
    return {
      fileUrl,
      keywords,
      currentPage,
    };
  },
});
</script>

本地路径引入示例:

import FilePreview from '@/components/file-preview/index.vue';

API

Props

| 参数 | 说明 | 类型 | 默认值 | 必填 | |------|------|------|--------|------| | url | 文件资源的 URL 地址 | string | '' | 是 | | highlight | 需要高亮的关键词数组 | string[] | [] | 否 | | page | 当前页码(PDF/PPT 有效) | number | 1 | 否 | | showHighlight | 是否显示高亮 | boolean | true | 否 |

模板中推荐使用 kebab-case::show-highlight@close-loading 等。

Methods

通过 ref 取得子组件实例后,可调用:

| 方法名 | 说明 | 参数 | 返回值 | |--------|------|------|--------| | triggerFullFill | 用当前根节点 clientWidth 更新内部宽度(用于 PDF/PPT 随容器变宽重排);不调用浏览器全屏 API | - | void | | repositioning | 跳转到指定页(仅 PDF / PPT 有效;TXT/DOC 无操作) | page?: number, smooth?: boolean | void |

Vue 2.7(setup + ref)

const previewRef = ref(null);
// 调用:previewRef.value && previewRef.value.repositioning(5, true);

Options API

this.$refs.previewRef.repositioning(5, true);

使用示例

基础预览

<template>
  <file-preview :url="'https://example.com/document.pdf'" />
</template>

<script>
import { defineComponent } from 'vue';
import FilePreview from '@core-pilot/file-preview-vue2';

export default defineComponent({
  components: { FilePreview },
});
</script>

带关键词高亮

<template>
  <file-preview
    :url="fileUrl"
    :highlight="['重要', '注意', '关键']"
    :show-highlight="true"
  />
</template>

<script>
import { defineComponent, ref } from 'vue';
import FilePreview from '@core-pilot/file-preview-vue2';

export default defineComponent({
  components: { FilePreview },
  setup() {
    const fileUrl = ref('https://example.com/document.pdf');
    return { fileUrl };
  },
});
</script>

PDF 页码跳转

<template>
  <div>
    <button type="button" @click="jumpToPage(5)">跳转到第 5 页</button>
    <file-preview
      ref="previewRef"
      :url="pdfUrl"
      :page="currentPage"
    />
  </div>
</template>

<script>
import { defineComponent, ref } from 'vue';
import FilePreview from '@core-pilot/file-preview-vue2';

export default defineComponent({
  components: { FilePreview },
  setup() {
    const previewRef = ref(null);
    const pdfUrl = ref('https://example.com/document.pdf');
    const currentPage = ref(1);

    const jumpToPage = (page) => {
      currentPage.value = page;
      if (previewRef.value) {
        previewRef.value.repositioning(page, true);
      }
    };

    return {
      previewRef,
      pdfUrl,
      currentPage,
      jumpToPage,
    };
  },
});
</script>

动态切换文件

<template>
  <div>
    <button type="button" @click="switchFile">切换文件</button>
    <file-preview
      :url="currentFileUrl"
      :highlight="keywords"
    />
  </div>
</template>

<script>
import { defineComponent, ref } from 'vue';
import FilePreview from '@core-pilot/file-preview-vue2';

export default defineComponent({
  components: { FilePreview },
  setup() {
    const currentFileUrl = ref('https://example.com/file1.pdf');
    const keywords = ref(['关键词']);

    const switchFile = () => {
      currentFileUrl.value = 'https://example.com/file2.docx';
    };

    return {
      currentFileUrl,
      keywords,
      switchFile,
    };
  },
});
</script>

容器变宽后重算布局(triggerFullFill

在浏览器全屏、侧栏收起等导致预览区域宽度变化后,可调用 triggerFullFill(),用新的容器宽度刷新 PDF/PPT 的展示(与是否进入系统全屏无关,名称沿用历史接口)。

<template>
  <div>
    <button type="button" @click="relayout">容器变宽后重算</button>
    <file-preview
      ref="previewRef"
      :url="fileUrl"
    />
  </div>
</template>

<script>
import { defineComponent, ref } from 'vue';
import FilePreview from '@core-pilot/file-preview-vue2';

export default defineComponent({
  components: { FilePreview },
  setup() {
    const previewRef = ref(null);
    const fileUrl = ref('https://example.com/document.pdf');

    const relayout = () => {
      if (previewRef.value) {
        previewRef.value.triggerFullFill();
      }
    };

    return {
      previewRef,
      fileUrl,
      relayout,
    };
  },
});
</script>

Options API 示例(不使用 setup)

<template>
  <div>
    <file-preview
      ref="previewRef"
      :url="fileUrl"
      :highlight="keywords"
      :page="currentPage"
      :show-highlight="true"
    />
  </div>
</template>

<script>
import FilePreview from '@core-pilot/file-preview-vue2';

export default {
  components: {
    FilePreview,
  },
  data() {
    return {
      fileUrl: 'https://example.com/document.pdf',
      keywords: ['关键词1', '关键词2'],
      currentPage: 1,
    };
  },
  methods: {
    jumpToPage(page) {
      this.currentPage = page;
      this.$refs.previewRef.repositioning(page, true);
    },
  },
};
</script>

组件内部实现

文件类型识别

组件会根据 URL 的文件扩展名自动识别文件类型:

  • .doc, .docx → Word 文档预览
  • .pdf → PDF 预览
  • .ppt, .pptx → PowerPoint 预览
  • 其他 → 文本文件预览

子组件说明

  • TextPreview:处理纯文本文件
  • DocPreview:使用 docx-preview 渲染 Word
  • PdfPreview:使用 vue-pdf-embed 的 Vue 2 入口渲染 PDF
  • PptPreview:使用 pptx-preview 渲染 PPT

逻辑模块(hooks,实为组合函数)

useHighlight

文本高亮,基于 mark.js(源码为 hooks/useHighlight.js)。

useRender

下载与 Loading 文案相关:downloadWithSpeedupdateDownloadFinishtipsVNode 等。

样式定制

组件使用 Less,主要类名包括:

  • .filePreview:主容器
  • .fileContainer:单类型预览外层
  • .file-error:错误提示
  • .text-render.doc-render.pdf-render.ppt-render:各类型内容区

可在业务侧覆盖上述类名。

注意事项

  1. 跨域:文件 URL 需可访问,并按需配置 CORS
  2. 浏览器:建议使用现代浏览器;PDF 能力依赖 vue-pdf-embed / pdf.js
  3. 性能:频繁切换 URL 或页码时,内部已做部分防抖与监听优化
  4. 与 Vue 3 技术栈差异:本组件实现为 Vue 2 + Element UI;若你手头仍是 Vue 3 + Element Plus 的旧版 @core-pilot/client-vue 文档或产物,请勿与当前 Vue 2 版 FilePreview 混在同一应用入口。本仓库当前分支若已将 client-vue 切到 Vue 2,则包内导出的 FilePreview 即本组件,与独立 .tgz 二选一即可。

错误处理

加载失败时展示「文件打开失败」。常见原因:

  • URL 无效或网络不可达
  • 跨域被拒绝
  • 格式不支持或服务器错误

开发说明

目录结构

file-preview/
├── index.vue           # 主组件
├── LocalDebugDemo.vue  # 本地调试壳层(Vite / Storybook 共用)
├── textPreview.vue
├── docPreview.vue
├── pdfPreview.vue
├── pptPreview.vue
├── hooks/
│   ├── useHighlight.js
│   └── useRender.js
├── extensions/
│   └── highlight.js
├── style/
│   └── index.less
└── stories/            # Storybook 示例(不随 npm pack 发布)

扩展新格式

  1. index.vue 中增加类型分支
  2. 新增对应 xxxPreview.vue
  3. 在模板中挂载子组件

License

MIT