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

@wanghe1995/docx-editor-ui

v1.0.0

Published

docx editor完整ui编辑器

Readme

docx-editor

基于 Canvas 的类 Word 文档编辑器,提供分页渲染与富文本编辑能力,并支持导入 .docx(基于 docx-preview 解析为编辑器元素)。

  • 仓库主页:https://gitee.com/wanghe520/docx-editor
  • NPM 包名:@wanghe1995/docx-editor

功能概览

  • 富文本:撤销/重做、字体/字号、加粗/斜体/下划线/删除线、高亮、上下标、对齐、标题、列表等
  • 插入:表格、图片、链接、代码块、分页符、公式、日期、图表、音视频、条形码/二维码等
  • 文档结构:页眉/页脚、页码、页边距、分页、水印、目录、批注
  • 扩展能力:快捷键/右键菜单可注册,自定义插件机制

安装

npm i @wanghe1995/docx-editor

UI 方案会使用以下 peer 依赖(由业务项目安装):

  • vue
  • element-plus
  • @element-plus/icons-vue
  • prismjs

快速开始

方案 A:作为整套 UI 使用(推荐)

该方案会挂载本仓库 Demo 同款 UI(顶部栏/侧边栏/弹窗/编辑器等),适合业务快速接入。

import { mountDocxEditorUI } from '@wanghe1995/docx-editor/ui'

const { api, unmount } = mountDocxEditorUI('#app')

api.on('ready', () => {
  console.log('docx-editor ready')
})

// unmount()

指定 Element Plus 语言包:

import { mountDocxEditorUI } from '@wanghe1995/docx-editor/ui'
import zhCn from 'element-plus/es/locale/lang/zh-cn'

mountDocxEditorUI('#app', { locale: zhCn })

方案 B:作为核心库使用(更灵活)

适合你有自己的 UI,只需要编辑器内核能力。

import DocxEditor, { EditorMode } from '@wanghe1995/docx-editor'

const container = document.querySelector<HTMLDivElement>('#editor')!
const editor = new DocxEditor(container, { main: [{ value: 'Hello Docx Editor' }] }, {})

editor.command.executeMode(EditorMode.EDIT)

销毁:

editor.destroy()

UI 模式 API(@wanghe1995/docx-editor/ui

mountDocxEditorUI

import { mountDocxEditorUI } from '@wanghe1995/docx-editor/ui'

签名(概念说明):

mountDocxEditorUI(
  target: string | HTMLElement,
  options?: {
    locale?: Language
    onAppCreated?: (app: VueApp) => void
    initialDocument?: {
      meta: DocumentMeta
      url?: string
      format?: 'word' | 'canvas'
    }
    documentApi?: DocumentApi
  }
): {
  app: VueApp
  unmount(): void
  executeCommand(command: string, ...args: any[]): void
  api: DocxEditorUiExternalApi
}

参数说明:

  • target:挂载点(CSS selector 或 HTMLElement)
  • options.locale:Element Plus 语言包
  • options.onAppCreated:可用于注册插件/注入全局能力
  • options.initialDocument:初始化加载的文档信息(见下文)
  • options.documentApi:后端对接实现(推荐注入;见下文)

返回值说明:

  • unmount():卸载 UI(SPA 路由切换时使用)
  • executeCommand(...):透传 UI 内部命令(一般不建议作为主集成方式)
  • api:推荐使用的外部 API(事件订阅、保存、快照等)

初始化加载(initialDocument

UI 挂载时可传入 initialDocument 自动拉取并渲染远程文档。

要点:

  • initialDocument.meta 与后端保存/状态接口使用同一套 DocumentMeta
  • 拉取地址优先 initialDocument.url,否则使用 initialDocument.meta.path
import { mountDocxEditorUI } from '@wanghe1995/docx-editor/ui'

mountDocxEditorUI('#app', {
  initialDocument: {
    meta: {
      id: 'doc-10001',
      path: 'https://example.com/demo.docx',
      status: 'edit',
      name: '演示文档',
      createdAt: new Date().toISOString(),
      submittedAt: ''
    },
    format: 'word'
  }
})

UI 外部 API(事件 / 节流 / 保存)

mountDocxEditorUI 返回的 api 用于业务侧订阅变化并对接后端。

api.on / api.off

const unsubscribe = api.on(
  'contentChange',
  async (payload) => {
    console.log(payload)
  },
  { debounceMs: 1200, maxWaitMs: 8000 }
)

unsubscribe()

事件订阅参数:

  • debounceMs:防抖间隔(推荐用于保存)
  • maxWaitMs:最长等待(避免持续输入时一直不触发)
  • throttleMs:节流间隔(推荐用于 mode/ability 等高频事件)

建议策略:

  • 自动保存:{ debounceMs: 800~1500, maxWaitMs: 5000~15000 }
  • 模式/能力同步:{ throttleMs: 200~500 }

事件列表与 payload

ready

  • payload:undefined

metaChange

  • payload:{ meta: DocumentMeta }

statusChange

  • payload:{ status: 'edit' | 'lock' }

contentChange

  • payload:{ meta: DocumentMeta; content: unknown }
  • 触发时机:编辑器内容被修改(已内置 1s 防抖;建议业务侧再做“保存节流”)

modeChange

  • payload:{ mode: string; ability?: { focused: boolean; readonly: boolean; disabled: boolean; canInput: boolean } }
  • 触发时机:调用 UI 的 mode 命令切换模式

abilityChange

  • payload:{ focused: boolean; readonly: boolean; disabled: boolean; canInput: boolean }
  • 触发时机:选区/区域变化导致能力变化(例如进入表单控件区域、只读区域等)

api.document

常用能力:

  • api.document.getMeta():获取当前文档元信息
  • api.document.setMeta(partial):更新元信息(例如改名)
  • api.document.getSnapshot():获取 { meta, content } 快照(用于业务保存)
  • api.document.save({ silent?: boolean }):触发一次保存(走 DocumentApi)

后端对接(保存 / 保护 / 解锁)

DocumentApi(推荐注入)

UI 模式推荐在 mountDocxEditorUI(..., { documentApi }) 注入你的后端实现,编辑器内部会统一调用它完成保存与状态变更。

import type { DocumentApi } from '@wanghe1995/docx-editor'
import { mountDocxEditorUI } from '@wanghe1995/docx-editor/ui'

const documentApi: DocumentApi = {
  async saveDocument(payload) {
    const resp = await fetch('https://your-domain.com/document/save', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload)
    })
    if (!resp.ok) throw new Error(`saveDocument failed: ${resp.status}`)
    return await resp.json()
  },
  async setStatus(payload) {
    const resp = await fetch('https://your-domain.com/document/status', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload)
    })
    if (!resp.ok) throw new Error(`setStatus failed: ${resp.status}`)
  }
}

mountDocxEditorUI('#app', { documentApi })

VITE_DOCUMENT_API_BASE_URL(仅作为默认实现的便捷配置)

当你不注入 documentApi 时,UI 会启用“默认 DocumentApi”:

  • 配置了 VITE_DOCUMENT_API_BASE_URL:自动请求你的后端
  • 未配置:本地兜底(用于 Demo 体验,不建议生产使用)

示例(运行本仓库 Demo 时使用):

在项目根目录创建 .env.local

VITE_DOCUMENT_API_BASE_URL=http://localhost:8080

默认请求:

  • POST {VITE_DOCUMENT_API_BASE_URL}/document/save
  • POST {VITE_DOCUMENT_API_BASE_URL}/document/status

接口约定(建议)

保存文档:

POST /document/save

{
  "meta": { "id": "1", "path": "/demo", "status": "edit" },
  "content": { "version": "x.y.z", "data": { "main": [{ "value": "..." }] }, "options": {} }
}

返回:

{ "submittedAt": "2026-01-01T00:00:00.000Z" }

保护/解锁:

POST /document/status

{ "id": "1", "path": "/demo", "status": "lock", "password": "123456" }

核心库 API(@wanghe1995/docx-editor

new DocxEditor(container, data, options) 返回编辑器实例,核心入口:

  • editor.command:命令入口(编辑能力)
  • editor.listener:监听器入口(单回调槽位)
  • editor.eventBus:事件总线(多订阅者)
  • editor.register:注册入口(快捷键/右键菜单/i18n 等)
  • editor.use(...):插件机制
  • editor.destroy():销毁

常用命令示例:

import DocxEditor, { EditorMode } from '@wanghe1995/docx-editor'

const editor = new DocxEditor(container, { main: [{ value: 'Hello' }] }, {})

const snapshot = editor.command.getValue()
editor.command.executeSetValue({
  data: { main: [{ value: '已加载的内容' }] },
  options: editor.command.getOptions()
})

editor.command.executeMode(EditorMode.EDIT)
editor.command.executeMode(EditorMode.READONLY)

开发

运行 Demo:

npm install
npm run dev

构建:

npm run build
npm run build:local
npm run lib

质量检查:

npm run lint
npm run type:check