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

@itshixun/qckeditor-vue3

v1.2.4

Published

Vue3 components for CKEditor 5

Readme

@itshixun/qckeditor-vue3

Vue 3 组件库,用于 CKEditor 5 富文本编辑器。

本次更新为文档补充:将 v1.1.1 ~ v1.1.3 期间已发布的能力完整收录进 README,便于查阅。

已收录的近期能力:

  • QCKEditor 组件,支持 classic / inline / document 三种编辑器类型(v1.1.3)
  • locale 属性,透传 CKEditor / QCKEditor / QCKClassic / QCKEditorPro,按语言动态加载 CKEditor 5 官方语言包,支持运行时切换
  • dataNormalizer 属性,透传 CKEditor / QCKEditor / QCKClassic / QCKEditorPro,用于格式化初始值与外部 modelValue 变更(v1.1.1 / v1.1.2)
  • CKEditorQCKContentfontSize 属性(px),通过 CSS 变量 --ck-content-font-size 应用
  • QCKEditor 默认合并「段落 + 标题 1~5」的标题配置与「标记(marker)」高亮配置,与历史版本行为保持一致
  • QCKEditorProdisableExit 属性与 exit-blocked 事件,用于在编辑器内部异步操作(PendingActions)期间控制是否退出编辑模式

安装

npm install @itshixun/qckeditor-vue3
# 或
pnpm add @itshixun/qckeditor-vue3
# 或
yarn add @itshixun/qckeditor-vue3

对等依赖

本库需要以下对等依赖:

npm install vue@^3.0.0 ckeditor5@>=42.0.0

使用

引入样式

在使用组件前,需要引入本库的样式文件:

import '@itshixun/qckeditor-vue3/dist/index.css';

本样式文件已内置 CKEditor 5 官方样式,无需再单独引入 ckeditor5/ckeditor5.css

基础编辑器(CKEditor)

底层 CKEditor 封装组件,支持任意 CKEditor 构建:

<template>
  <CKEditor v-model="content" :editor="ClassicEditor" :config="editorConfig" />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { ClassicEditor } from 'ckeditor5';
import { CKEditor } from '@itshixun/qckeditor-vue3';
import '@itshixun/qckeditor-vue3/dist/index.css';

const content = ref('');
const editorConfig = {
  toolbar: ['bold', 'italic', 'link', 'bulletedList', 'numberedList'],
};
</script>

通用编辑器(QCKEditor)

支持三种编辑器类型,由 type prop 切换:

  • classic(默认):经典编辑器,工具栏固定在顶部
  • inline:行内编辑器,工具栏在选中内容时浮动显示
  • document:文档编辑器(基于 DecoupledEditor),工具栏与编辑区分离挂载,高度自适应容器

QCKEditor 在用户传入 config 之上,预设了与历史版本一致的默认配置:

  • 标题:在官方「段落 + 标题 1~3」基础上扩展支持「标题 4 / 标题 5」(heading4 / heading5),并通过 src/styles/index.css 统一定义了 h1~h5 字号样式
  • 高亮(Highlight):仅提供「标记(marker)」一项,配套样式 .marker-default

用户 config 中显式提供的同名字段会覆盖默认配置(深度合并)。

<template>
  <!-- 经典编辑器(默认) -->
  <QCKEditor v-model="content" :config="editorConfig" />

  <!-- 行内编辑器 -->
  <QCKEditor v-model="content" type="inline" :config="editorConfig" />

  <!-- 文档编辑器(工具栏与编辑区独立容器) -->
  <QCKEditor v-model="content" type="document" :config="editorConfig" />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { QCKEditor } from '@itshixun/qckeditor-vue3';
import '@itshixun/qckeditor-vue3/dist/index.css';

const content = ref('');
const editorConfig = {
  toolbar: ['bold', 'italic', 'link'],
};
</script>

经典编辑器(QCKClassic)

预配置的经典编辑器组件:

<template>
  <QCKClassic v-model="content" :config="editorConfig" />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { QCKClassic } from '@itshixun/qckeditor-vue3';
import '@itshixun/qckeditor-vue3/dist/index.css';

const content = ref('');
const editorConfig = {
  toolbar: ['bold', 'italic', 'link'],
};
</script>

专业版编辑器(QCKEditorPro)

点击激活的编辑器,提升页面性能:

<template>
  <QCKEditorPro
    v-model="content"
    :config="editorConfig"
    placeholder="点击编辑内容"
    :min-height="100"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { QCKEditorPro } from '@itshixun/qckeditor-vue3';
import '@itshixun/qckeditor-vue3/dist/index.css';

const content = ref('');
const editorConfig = {
  toolbar: ['bold', 'italic'],
};
</script>

内容展示(QCKContent)

安全渲染编辑器内容:

<template>
  <QCKContent :content="htmlContent" />
</template>

<script setup lang="ts">
import { QCKContent } from '@itshixun/qckeditor-vue3';
import '@itshixun/qckeditor-vue3/dist/index.css';

const htmlContent = '<p>Hello <strong>World</strong></p>';
</script>

图片预览(imagePreview)

默认关闭。开启后,点击内容中的图片会打开内置轻量预览弹层(QCKImageViewer),支持关闭(遮罩/×/Esc)、左右切换(按钮/方向键)、计数、缩放(按钮/滚轮)、拖拽平移、双击复位、全屏与底部缩略图栏:

<template>
  <!-- 布尔用法:全部默认配置 -->
  <QCKContent :content="htmlContent" :image-preview="true" />

  <!-- 对象用法:覆盖配置 -->
  <QCKContent :content="htmlContent" :image-preview="{ zIndex: 3000, navbar: false }" />
</template>

imagePreview 对象形式支持的选项(QCKImagePreviewOptions):

| 选项 | 类型 | 默认值 | 说明 | |------|------|--------|------| | zIndex | Number | 2100 | 预览弹层 z-index | | loop | Boolean | true | 切换到底/顶后是否循环 | | navbar | Boolean | true | 底部缩略图栏(图片数 > 1 时显示) | | fullscreen | Boolean | true | 是否显示全屏按钮 |

QCKEditorPro 同样支持 imagePreview,会透传给预览态的内容区(预览态点击图片只打开预览,不会激活编辑器)。

图片加载失败重试(imageRetry)

默认开启。适用于新生成的富文本内容中,图片资源正在服务端上传、尚未存储到对象存储的场景:图片加载失败后按固定间隔自动重试,直到成功或达到最大次数。重试通过重设相同 src 触发重新请求,不追加额外参数,不会破坏签名 URL:

<template>
  <!-- 布尔用法:全部默认配置(可省略) -->
  <QCKContent :content="htmlContent" :image-retry="true" />

  <!-- 对象用法:覆盖配置 -->
  <QCKContent :content="htmlContent" :image-retry="{ maxRetries: 20, interval: 1000 }" />

  <!-- 关闭重试 -->
  <QCKContent :content="htmlContent" :image-retry="false" />
</template>

imageRetry 对象形式支持的选项(QCKImageRetryOptions):

| 选项 | 类型 | 默认值 | 说明 | |------|------|--------|------| | maxRetries | Number | 10 | 单张图片最大重试次数 | | interval | Number | 500 | 重试间隔(毫秒) |

QCKEditorPro / QCKEditor / QCKClassic 同样支持 imageRetry:预览态(QCKContent)与编辑态(编辑区 DOM)均生效。

界面语言(locale)

所有编辑器组件(CKEditor / QCKEditor / QCKClassic / QCKEditorPro)支持 locale 属性,默认 'zh-cn'。组件会按 locale 动态加载对应的 CKEditor 5 官方语言包(构建为独立的懒加载 chunk,不增加首屏体积),并写入编辑器配置的 languagetranslations 字段:

<template>
  <!-- 简体中文(默认) -->
  <QCKEditor v-model="content" locale="zh-cn" />

  <!-- 英文 / 日文 / 繁体中文 -->
  <QCKEditor v-model="content" locale="en" />
  <QCKEditorPro v-model="content" locale="ja" />
  <QCKClassic v-model="content" locale="zh" />
</template>
  • 写法兼容'zhCN' / 'zh-CN' / 'zh_CN' / 'ZH-CN' 等写法均可,内部统一规范化为 CKEditor 5 语言包格式(小写 + 连字符)
  • 支持语言:覆盖 CKEditor 5 官方全部语言包(zh-cnzhenen-gbjakodefrpt-br 等 70+);传入不支持的语言时会输出警告并回退为默认语言
  • 动态变更:运行时修改 locale 会销毁并以当前内容重建编辑器实例(CKEditor 5 不支持运行时原地切换语言);重建对外只触发一次新的 ready 事件,不会触发 destroy
  • 优先级config 中显式传入的 language / translations 优先于 locale 的派生值
<script setup lang="ts">
import { ref } from 'vue';

const locale = ref('zh-cn');
// 运行时切换:编辑器保留内容重建,界面语言变为英文
locale.value = 'en';
</script>

上传适配器

本库提供了三种上传适配器,用于处理编辑器中的文件上传(图片、音视频等):

1. XHR 上传适配器(createXHRUploadAdapter)

基于 XMLHttpRequest 的标准上传方式,适用于大多数后端直传场景:

import { FileRepository } from 'ckeditor5';
import { createXHRUploadAdapter } from '@itshixun/qckeditor-vue3';

const editorConfig = {
  // ...其他配置
  extraPlugins: [
    function CustomUploadAdapterPlugin(editor) {
      editor.plugins.get(FileRepository).createUploadAdapter = (loader) => {
        return createXHRUploadAdapter(loader, {
          uploadUrl: 'https://api.example.com/upload',
          headers: { Authorization: 'Bearer token' },
          withCredentials: true,
          fieldName: 'file',
          extraFormData: { category: 'images' },
        });
      };
    },
  ],
};

2. 自定义异步上传适配器(createAsyncUploadAdapter)

支持自定义异步上传流程,适用于 S3、华为云 OBS 等需要多步上传的场景:

import { FileRepository } from 'ckeditor5';
import { createAsyncUploadAdapter } from '@itshixun/qckeditor-vue3';

const editorConfig = {
  extraPlugins: [
    function CustomUploadAdapterPlugin(editor) {
      editor.plugins.get(FileRepository).createUploadAdapter = (loader) => {
        return createAsyncUploadAdapter(loader, async (file, updateProgress) => {
          // 示例:上传到对象存储(预签名 URL 模式)

          // 第1步:从后端获取预签名上传 URL
          const presignRes = await fetch('/api/presign-upload', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ filename: file.name, contentType: file.type }),
          });
          const { uploadUrl, finalUrl } = await presignRes.json();

          // 第2步:直传到对象存储(使用 XMLHttpRequest 以便监听进度)
          await new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.open('PUT', uploadUrl, true);
            xhr.setRequestHeader('Content-Type', file.type);

            xhr.upload.addEventListener('progress', (evt) => {
              if (evt.lengthComputable && updateProgress) {
                updateProgress(Math.round((evt.loaded / evt.total) * 100));
              }
            });
            xhr.addEventListener('load', () => {
              xhr.status >= 200 && xhr.status < 300 ? resolve(void 0) : reject('上传失败');
            });
            xhr.addEventListener('error', () => reject('上传出错'));
            xhr.send(file);
          });

          // 第3步:返回最终访问 URL
          return finalUrl;
        });
      };
    },
  ],
};

也可以返回 UploadResponse 对象:

createAsyncUploadAdapter(loader, async (file, updateProgress) => {
  // ...上传逻辑

  return {
    default: 'https://cdn.example.com/image.jpg',  // 默认 URL(必须)
    url: 'https://cdn.example.com/image.jpg',      // 可选
    // 还可以返回其他字段
  };
});

3. Mock 上传适配器(createMockUploadAdapter)

用于演示环境,模拟上传过程和进度更新:

import { FileRepository } from 'ckeditor5';
import { createMockUploadAdapter } from '@itshixun/qckeditor-vue3';

const editorConfig = {
  extraPlugins: [
    function CustomUploadAdapterPlugin(editor) {
      editor.plugins.get(FileRepository).createUploadAdapter = (loader) => {
        return createMockUploadAdapter(loader);
      };
    },
  ],
};

Props

CKEditor

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | editor | Function | 必填 | CKEditor 构建类 | | config | Object | {} | 编辑器配置 | | tagName | String | 'div' | 渲染标签 | | disabled | Boolean | false | 是否禁用 | | disableTwoWayDataBinding | Boolean | false | 禁用双向绑定 | | dataNormalizer | Function | (data) => data | 格式化初始值与外部 modelValue 变更的函数 | | fontSize | Number | - | 编辑区正文字号(px),通过 CSS 变量 --ck-content-font-size 应用 | | locale | String | 'zh-cn' | 编辑器界面语言,兼容 'zhCN' / 'zh-CN' / 'zh_CN' 等写法;动态变更会重建编辑器实例(见界面语言说明) |

QCKEditor

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | type | 'classic' \| 'inline' \| 'document' | 'classic' | 编辑器类型,非法值兜底为 classic | | config | Object | {} | 编辑器配置(与默认 highlight / heading 配置深度合并) | | tagName | String | 'div' | 渲染标签 | | disabled | Boolean | false | 是否禁用 | | disableTwoWayDataBinding | Boolean | false | 禁用双向绑定 | | dataNormalizer | Function | (data) => data | 格式化初始值与外部 modelValue 变更的函数 | | imageRetry | Boolean | Object | true | 编辑区图片加载失败重试(见 QCKContent 图片重试说明) | | locale | String | 'zh-cn' | 编辑器界面语言,透传给 CKEditor(见界面语言说明) |

默认配置说明:QCKEditor 预置了「段落 + 标题 1~5」的标题选项,以及「标记(marker)」高亮选项,与历史版本编辑器一致。用户 config 中显式提供同名字段会覆盖默认值。

QCKEditorready 等事件中传入的编辑器实例类型为 ClassicEditor | InlineEditor | DecoupledEditor(即 QEditorInstance 联合类型)。

QCKClassic

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | config | Object | {} | 编辑器配置 | | tagName | String | 'div' | 渲染标签 | | disabled | Boolean | false | 是否禁用 | | disableTwoWayDataBinding | Boolean | false | 禁用双向绑定 | | dataNormalizer | Function | (data) => data | 格式化初始值与外部 modelValue 变更的函数 | | imageRetry | Boolean | Object | true | 编辑区图片加载失败重试(透传给 QCKEditor) | | locale | String | 'zh-cn' | 编辑器界面语言,透传给 QCKEditor(见界面语言说明) |

QCKEditorPro

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | config | Object | {} | 编辑器配置 | | content | String | - | 初始内容 | | placeholder | String | '点击编辑内容' | 占位文本 | | minHeight | Number | 95 | 最小高度(px) | | height | Number | 0 | 固定高度(px) | | fitHeight | Boolean | false | 适应父容器高度 | | contentBgColor | String | 'rgb(0 0 0 / 2%)' | 背景色 | | contentBgHoverColor | String | 'rgb(0 0 0 / 4%)' | 悬停背景色 | | borderRadius | Number | 4 | 圆角大小 | | sanitize | Boolean | true | 是否清洗 HTML | | horizontalPadding | Number | String | 'var(--ck-spacing-standard)' | 预览态水平 padding,数字按 px 处理(透传 QCKContent) | | verticalPadding | Number | String | 'var(--ck-spacing-standard)' | 预览态垂直 padding,用法同 horizontalPadding(透传 QCKContent) | | trimMargin | Boolean | true | 预览态消除首尾段落 margin(透传 QCKContent) | | imagePreview | Boolean | Object | false | 预览态图片预览(见 QCKContent 图片预览说明) | | imageRetry | Boolean | Object | true | 预览态与编辑态图片加载失败重试(见 QCKContent 图片重试说明) | | dataNormalizer | Function | (data) => data | 格式化初始内容与外部变更的函数 | | disableExit | Boolean | false | 外部禁用退出编辑模式;与编辑器内部异步操作(PendingActions)共同决定 exit-blocked | | locale | String | 'zh-cn' | 编辑器界面语言,透传给 QCKClassic(见界面语言说明) |

QCKContent

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | content | String | - | HTML 内容 | | containerClass | String | '' | 容器类名 | | sanitize | Boolean | true | 是否清洗 HTML | | math | Boolean | true | 是否渲染 span.math-tex 中的 KaTeX 公式 | | highlightCode | Boolean | true | 是否对 pre code 应用 highlight.js 高亮 | | fontSize | Number | - | 渲染区正文字号(px),通过 CSS 变量 --ck-content-font-size 应用 | | horizontalPadding | Number | String | 'var(--ck-spacing-standard)' | 水平 padding,数字按 px 处理 | | verticalPadding | Number | String | 'var(--ck-spacing-standard)' | 垂直 padding,用法同 horizontalPadding | | trimMargin | Boolean | true | 消除首尾段落 margin:首个 p 上间距、末个 p 下间距置 0 | | imagePreview | Boolean | Object | false | 图片预览,true 或 QCKImagePreviewOptions 对象(见上文) | | imageRetry | Boolean | Object | true | 图片加载失败重试,true 或 QCKImageRetryOptions 对象(见上文) |

事件

所有编辑器组件都支持以下事件:

| 事件 | 参数 | 说明 | |------|------|------| | ready | (editor) | 编辑器就绪 | | destroy | - | 编辑器销毁 | | blur | (event, editor) | 失去焦点 | | focus | (event, editor) | 获得焦点 | | input | (data, event, editor) | 内容变化 |

QCKEditorPro 还会发出:

| 事件 | 参数 | 说明 | |------|------|------| | exit-blocked | (reason: 'pending-actions' \| 'prop') | 退出编辑模式被阻止。pending-actions 表示编辑器内部仍有异步操作(如上传未完成),prop 表示 disableExittrue |

类型导出

import type {
  Props,
  ExtractEditorType,
  QCKImagePreviewOptions,
  QCKImageRetryOptions,
  QEditorType,
  QEditorInstance,
} from '@itshixun/qckeditor-vue3';

注意事项

  1. CKEditor 授权: 本库使用 CKEditor 5 的 GPL 授权。如需商业使用,请购买 CKEditor 商业授权

  2. 样式文件: 导入 @itshixun/qckeditor-vue3/dist/index.css 即可,该文件已内置 CKEditor 5 官方样式。

  3. HTML 清洗: QCKContentQCKEditorPro 默认开启 XSS 防护,会自动过滤危险标签和属性。

  4. QCKEditor 默认配置: QCKEditor 会自动合并「段落 + 标题 1~5」的标题选项与「标记(marker)」高亮选项。覆盖方式:在 config.heading.optionsconfig.highlight.options 中提供完整数组(lodash merge 按索引合并)。

  5. dataNormalizer: 用于在写入编辑器前格式化内容(初始值与外部 modelValue 变更都会经过此函数)。返回值为字符串;常见用途:清理历史版本遗留的脏标签、统一空白与编码。

  6. 异步操作与退出编辑: QCKEditorProPendingActions 仍有任务时(即文件上传、撤销恢复队列非空等)会阻止退出编辑模式,并通过 exit-blocked 事件通知业务方。可结合 disableExit 强制阻止。

  7. locale 与动态切换: 语言包按需懒加载,仅使用到的语言会进入运行时加载。修改 locale 会重建编辑器实例(内容保留),频繁切换有性能开销;若 config 中已显式配置 language / translations,则以 config 为准。

License

MIT