Sym - 一个用 Java 实现的现代化社区平台 • 源码 • 注册

Pipe - 小而美的开源博客平台 • 体验 • 皮肤
Solo - 一个用 Java 实现的博客系统,为你或你的团队创建个博客吧! • 源码下载 
Wide - 一个基于 Web 的 Go 语言 IDE • 教程试用

Vditor 使用指南

Vditor
下一代的 Markdown 编辑器,为未来而构建

npm bundle size




Start

CommonJS

  • 安装依赖
npm install vditor --save
  • 在代码中引入并初始化对象,可参考 index.js
import Vditor from 'vditor'
import "~vditor/src/assets/scss/classic" // 或者使用 dark

const vditor = new Vditor(id, {options...})
vditor.focus()

HTML script

  • 在 HTML 中插入 css 和 js,可参考 static.html
<!-- ⚠️生产环境请指定版本号,如 https://cdn.jsdelivr.net/npm/vditor@x.x.x/dist... -->
<!-- 可使用 index.dark.css 或 index.classic.css -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vditor/dist/index.classic.css" />
<script src="https://cdn.jsdelivr.net/npm/vditor/dist/index.min.js" defer></script>
const vditor = new Vditor(id, {options...})
vditor.focus()

Example Code

Screenshot

classic

black

API

options

说明 默认值
cache 是否使用 localStorage 进行缓存 true
height 编辑器总高度 'auto'
width 编辑器总宽度,支持 % 'auto'
placeholder 输入区域为空时的提示 ''
lang 多语言:en_US, zh_CN 'zh_CN'
counter 计数器 0
input 输入后触发 (value: string, previewElement?: HTMLElement): void -
focus 聚焦后触发 (value: string): void -
blur 失焦后触发 (value: string): void -
esc esc 按下后触发 (value: string): void -
ctrlEnter ⌘/ctrl+enter 按下后触发 (value: string): void -
select 编辑器中选中文字后触发 (value: string): void -
tab tab 键操作字符串,支持 \t 及任意字符串 -

options.toolbar

  • 工具栏,可使用 name 进行简写:toolbar: ['emoji', 'br', 'bold', '|', 'line']。默认值参见 src/ts/util/Options.ts
  • name 可枚举为:emoji, headings, bold, italic, strike, |, line, quote, list, ordered-list, check, code, inline-code, undo, redo, upload, link, table, record, both, preview, fullscreen, info, help, br
  • name 不在枚举中时,可以添加自定义按钮,格式如下:
{
      hotkey: '⌘-⇧-f',
      name: 'format',
      tipPosition: 'ne',
      tip: 'format',
      icon: '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="768" height="768" viewBox="0 0 768 768"><path d="M342 426v-84h426v84h-426zM342 256v-86h426v86h-426zM0 0h768v86h-768v-86zM342 598v-86h426v86h-426zM0 214l170 170-170 170v-340zM0 768v-86h768v86h-768z"></path></svg>',
      click: () => {
          alert('custom toolbar')
      },
}
说明 默认值
name 唯一标示 -
icon svg 图标 -
tip 提示 -
tipPosition 提示位置:ne, nw -
hotkey 快捷键,支持 ⌘/ctrl-key 或 ⌘/ctrl-⇧/shif-key 格式的配置 -
suffix 插入编辑器中的后缀 -
prefix 插入编辑器中的前缀 -
click 自定义按钮点击时触发的事件 ():viod -

options.preview

说明 默认值
delay 预览 debounce 毫秒间隔 1000
mode 显示模式:'both', 'editor', 'preview' 'both'
parse 预览回调 (element: HTMLElement): void -
url md 解析请求 -

options.preview.hljs

说明 默认值
enable 是否启用代码高亮 true
style highlight.js 样式文件名 'atom-one-light'

options.hint

说明 默认值
delay 提示 debounce 毫秒间隔 200
emoji 默认表情,可从 lute/emoji_map 中选取,也可自定义 {'+1': '👍', '-1': '👎', 'heart': '❤️', 'cold_sweat': '😰'}
emojiTail 常用表情提示 -
emojiPath 表情图片地址 https://cdn.jsdelivr.net/npm/vditor/src/assets/emoji
at @用户回调,(value: string): Array,需同步返回数组 [{value:'', html:''}] -

options.upload

⚠️ filename 需和 options.uploads.filename 保持一致,否则将导致编辑器中出现多个链接
后端上传返回数据不一致时,可使用 format 将其转换为如下内置的数据结构:

{
    "msg": "",
    "code": 0,
    "data": {
        "errFiles": ['filename', 'filename2'],
        "succMap": {
            "filename3": "filepath3",
            "filename3": "filepath3"
        }
    }
}
说明 默认值
url 上传 url,查看规范 ''
max 上传文件最大 Byte 10 * 1024 * 1024
linkToImgUrl 剪切板中包含图片地址时,使用此 url 重新上传 ''
success 上传成功回调 (editor: HTMLPreElement, msg: string): void -
error 上传失败回调 (msg: string): void -
token CORS 上传验证,头为 X-Upload-Token -
filename 文件名安全处理 (name: string): string name => name.replace(/\W/g,'')
accept 文件上传类型,同 input accept -
validate 校验,成功时返回 true 否则返回错误信息 (files: File[]) => string | boolean -
handler 自定义上传,当发生错误时返回错误信息 (files: File[]) => string | null -
format 对服务端返回的数据进行转换,以满足内置的数据结构 (files: File[], responseText: string): string -

options.resize

说明 默认值
enable 是否支持大小拖拽 false
position 拖拽栏位置:top, bottom 'bottom'
after 拖拽结束的回调 (height: number): void -

options.classes

说明 默认值
preview 预览元素上的 className ''

options.hotkey

说明 默认值
deleteLine 删除光标所在行或选中的行 ⌘-Backspace
duplicate 复制当前行或选中的内容 ⌘-d

methods

说明
getValue() 获取编辑器内容
getHTML() 获取预览区内容。该方法需使用异步编程
insertValue(value: string) 在焦点处插入内容
focus() 聚焦到编辑器
blur() 让编辑器失焦
disabled() 禁用编辑器
enable() 接触编辑器禁用
setSelection(start: number, end: number) 选中从 start 开始到 end 结束的字符串
getSelection():string 返回选中的字符串
setValue(value: string) 设置编辑器内容
renderPreview(value?: string) 设置预览区域内容
getCursorPosition():{top: number, left: number} 获取焦点位置
deleteValue() 删除选中内容
updateValue(value: string) 更新选中内容
isUploading() 上传是否还在进行中
clearCache() 清除缓存
disabledCache() 禁用缓存
enableCache() 启用缓存
html2md(value: string) html 转 md。该方法需使用异步编程
tip(text:string, time:number) 消息提示。time 为 0 将一直显示
setPreviewMode(mode: string) 设置预览模式。mode: 'both', 'editor', 'preview'

static methods

  • 不需要进行编辑操作时,仅需引入 method.min.js 后如下直接调用
Vditor.mermaidRender(document)
import VditorPreview from 'vditor/dist/method.min'
VditorPreview.mermaidRender(document)
  • 需要对页面中的 Markdown 进行渲染时可直接调用 preview 方法,参数如下:
element: HTMLTextAreaElement    // 为保证 Markdown 的完整性,请将其包裹在 textarea 中
options?: IPreviewOptions {
    hljsStyle?: string;    // 高亮样式,默认为 'atom-one-light'
    enableHighlight?: boolean;    // 是否需要代码高亮,默认为 true
    customEmoji?: { [key: string]: string };    // 自定义 emoji,默认为 {}
    lang?: (keyof II18nLang);    // 语言,默认为 'zh_CN'
}
  • ⚠️method.min.jsindex.min.js 不可同时引入
说明
mathRender(element: HTMLElement, lang: (keyof II18nLang) = "zh_CN") 转换 element 中的文本为数学公式
mermaidRender(element: HTMLElement) 转换 element 中的文本为流程图 / 时序图 / 甘特图
codeRender(element: HTMLElement, lang: (keyof II18nLang) = "zh_CN") 为 element 中的代码块添加复制按钮
chartRender(element: (HTMLElement | Document) = document) 图表渲染
abcRender(element: (HTMLElement | Document) = document) 五线谱渲染
md2html(mdText: string): string markdown 文本转换为 html,该方法需使用异步编程
preview(element: HTMLTextAreaElement, options?: IPreviewOptions) 页面 Markdown 文章渲染
emojiRender(text: string, customEmoji?: { [key: string]: string }): string 替换文本中的 :emoji: 为 emoji
highlightRender(hljsStyle: string, enableHighlight: boolean, element?: HTMLElement | Document) 为 element 中的代码块进行高亮渲染
mediaRender(element: HTMLElement) 特定链接分别渲染为视频、音频、嵌入的 iframe

CSS

在 DOM 元素上添加 class="vditor-reset" 属性可对内容进行更为友好的展示。

Dev

升级

CHANGELOG

开发步骤

  1. 安装 node LTS 版本
  2. 下载 最新代码并解压
  3. 根目录运行 npm install
  4. npm run start 启动本地服务器,打开 http://localhost:9000
  5. 修改代码
  6. npm run build 打包代码到 dist 目录

注意事项


欢迎注册黑客派社区,开启你的博客之旅。让学习和分享成为一种习惯!

75 评论
Vanessa • 2019-06-19
回复 删除

如果要用内置的上传功能,格式需要如下

{
	code: 0,
	msg: '',
	errFiles: ['filename', 'filename2']
	succMap: {
		'filename': 'filepath',
		'filename2': 'filepath2',
	}
}
Tracy4ever • 2019-06-19
回复 删除

好的啊,filepath 相对路径可以吗?

Vanessa • 2019-06-19
回复 删除

相对路径比如在 /a/b/c 这样的页面里面会坏吧

bugelin • 2019-06-23
回复 删除

上传的时候不需要给 input 指定个 name 吗 为啥我 springMVC 会报空指针获取不到 大佬求解

Vanessa • 2019-06-23
回复 删除

前端是这样传送的

    const formData = new FormData();
    for (let i = 0, iMax = uploadFileList.length; i < iMax; i++) {
        formData.append("file[]", uploadFileList[i]);
    }
     xhr.send(formData);
xushijie10086 • 2019-07-23
回复 删除

请教一下自定义上传图片的问题image.png

如果这样上传成功之后,
如何将图片 url 插入输入框里 【】 <== 这样的

lisaem • 2019-07-29
回复 删除

一个小问题 希望有缘人回答一下。本人在自己的服务器上部署了博客 solo,用 vditor 编辑预览文章都没问题,今天来公司,想写点东西,发现预览功能无法使用,左边输入的内容,右边无法显示预览,一片空白。chrome 里面用 f12 抓了下网络请求,发现有个请求被公司内网屏蔽了,具体是 http:// 我的网址 / console/markdown/2html,这个请求失败导致的。

eclanp • 2019-08-16
回复 删除

$$
\Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt,.
$$

Tracy4ever • 2019-08-19
回复 删除

请问,是不是如果 upload 写了 handler 方法,那么就不能使用内置的成功和失败回调啊?可是不写 handler 的话是不是对后台传参也有要求啊?我看到内置的上传的传参是 form-data 格式,然后参数名是 file[], 但是如果同时传多张图片的时候,会传两个 file[]。传多张图片要做怎样的格式要求?

Tracy4ever • 2019-08-19
回复 删除

那如果使用内置的上传,是不是上传成功,则后台返回

{
	code: 0,
	msg: '',
	data: {
		errFiles: [],
		succMap: {
			'filname1': 'filePath1',
			'filname2': 'filePath2'
		}
	}
}

上传失败则后台返回

{
	code: 1,
	msg: '...',
	data: {
		errFiles: [filename1,filename2],
		succMap: {
		}
	}
}
Tracy4ever • 2019-08-19
回复 删除

如果使用内置上传多张图片,部分上传成功,部分上传失败,那后台返回的应该是上传成功的代码还是失败的代码啊?

Vanessa • 2019-08-19
回复 删除
  • 使用 handler 就需要自己完成上传的处理,对后台参数没有要求
  • 多个文件使用 formData.append("file[]", uploadFileList[i]);
  • 上传会存在某些文件成功,某些文件失败的情况,因此 errFiles 和 succMap 会同时存在。只要 xhr.status === 200 就可以了
Tracy4ever • 2019-08-20
回复 删除

我在使用内置的上传,在上传多张图片的时候,发现传过去的参数 file[]:binary,file[]:binary, 导致接口没办法返回理想的数据😭 这个是不是不能使用内置的上传了啊?

Tracy4ever • 2019-08-20
回复 删除

TIM图片20190820113538.png
后台返回了这样的格式,为什么预览的时候图片显示 404 呢?路径是乱码的