PowerEditor
Power Editor power by tiptap (prosemirror toolkit)
Most WYSIWYG Editor
基于Microsoft Fluent Design System设计
基于 Tiptap
所见即所得
# Propoties
属性(attr) | 类型(type) | 必填(required) | 默认值(default) | 说明(statement) |
---|---|---|---|---|
value | [string] | No | I’m running PowerEditor with Vue.js. 🎉 | 文本内容, 支持纯文本及 HTML |
editable | [bool] | No | true | 编辑器是否只读 |
placeholder | [string] | No | Write something … | 编辑器 Placeholder |
disabledPlaceholder | [bool] | No | false | 禁用编辑器 Placeholder |
contentMaxWidth | [number] | No | 900px | 内容最大显示宽度 |
editorBackground | [string(color)] | No | 编辑器内部背景色 | |
editorOutSideBackground | [string(color)] | No | 编辑器外部背景色 | |
mobileDisplayWidth | [number] | No | 768 | 移动端模式 |
showToolBar | [bool] | No | true | 显示菜单工具栏 |
toolbarHeight | [number] | No | 70 | 菜单栏高度 |
toolbarBackground | [string(color)] | No | 菜单栏背景 | |
toolbarBorderRadius | [number] | No | 8 | 菜单栏边框圆角 |
editablePaddingTop | [number] | No | N/A | 可编辑模式下的顶部内边距, 不定义时不生效 |
readOnlyPaddingTop | [number] | No | 5 | 只读模式下的顶部内边距 |
editablePaddingBottom | [number] | No | 315 | 可编辑模式下的底部内边距 |
readOnlyPaddingBottom | [number] | No | 55 | 只读模式下的底部内边距 |
imgInterceptor | [function] | No | N/A | 图片上传拦截器, 用于后置处理图像内的数据 |
mentionItemAttr | [object] | No | N/A | MentionItem 属性 |
starterKit | [object] | No | ()=>{} | StarterKit 相关自定义配置 |
showControlOnReadonly | [bool] | No | true | 只读模式下是否显示控制栏 |
mdDecNodeFuncsPlugins | [object] | No | N/A | Markdown 解码器自定义配置 |
mdFlags | [object] | No | N/A | Markdown 解码器自定义层级标记 |
foreground | [string(color)] | No | #958DF1 | 编辑器前景色 |
imgPreview | [bool] | No | true | 是否显示图片预览 |
imgLazyLoad | [bool] | No | false | 图片懒加载 |
theme | ['light','dark'] | No | light | 明暗主题风格 |
starterKit | [object] | No | ()=>{} | |
extensions | [array] | No | [] | |
showSave | [bool] | No | true | 是否显示保存按钮 |
# Events
事件名(Name) | 参数类型(args) | 说明(statement) |
---|---|---|
on-mounted | object | Editor 初始化完成时触发事件, 返回editor |
container-scroll | object | Editor 容器滚动时触发事件 |
change | object | Editor 内容改变时触发事件 |
content-change | object | Editor 外部修改内容时触发事件 |
save-json | string | 触发保存事件并以 json 形式保存 |
save-html | string | 触发保存事件并以 html 形式保存 |
# Hooks
- 保存内容函数
this.$refs.editor.save()
此举会触发save-json
和save-html
事件
- 内容转换为 Markdown
this.$refs.editor.saveMarkdown()
- Markdown 转换为内容
this.$refs.editor.computeMarkdown(markdown)
- 插入Markdown内容
this.$refs.editor.insertMarkdown(markdown)
# Slot
- Custom-buttons, Custom-buttons-front 或 Custom-buttons-[index] (
index
从0
开始代表每个分隔栏左侧的位置,index
最大为4
, 缺省时为最右侧尾部,custom-buttons-front
为最左侧头部)
自定义ToolBar
菜单工具栏按钮项
- editor: 当前
tiptap
editor 对象 - defaultClass: 默认 CSS 样式名
<power-editor>
<template v-slot:custom-buttons="x">
<fv-button :class="[x.defaultClass]">Content</fv-button>
</template>
</power-editor>
- Front Content
在正文前插入前序内容
<power-editor>
<template v-slot:front-content>
<div class="front-content-block"></div>
</template>
</power-editor>
# Appendix
# 1. MentionItem
组件所包含的属性如下
# Propoties
属性(attr) | 类型(type) | 必填(required) | 默认值(default) | 说明(statement) |
---|---|---|---|---|
value | [string] | No | N/A | |
placeholder | [string] | No | Write something … | |
mentionList | [array] | No | ||
filterFunc | [function] | No | ||
chooseItemCallback | [function] | No | ||
mentionClickCallback | [function] | No | ||
headerForeground | [string(color)] | No | rgba(0, 120, 212, 1) | |
showPopper | [bool] | No | false | |
theme | ['light','dark'] | No | light |
其中, mentionList
,filterFunc
,chooseItemCallback
,mentionClickCallback
,headerForeground
可在初始化Power Editor
时对MentionItemAttr
进行设定.
{
mentionList: (value) => [],
filterFunc: (listItem, value) => {
return true;
},
chooseItemCallback: (chooseItem, value) => {
console.log('chooseItemCallback');
},
mentionClickCallback: (chooseItem, value) => {
console.log('mentionClickCallback');
},
headerForeground: () => {
return this.foreground;
},
}
# 2. Markdown Decoder Plugins
你可以自定义ProseMirror
节点(node)或标记(mark)渲染的方式, 以实现自定义的Markdown
解析器。
PowerEditor
的Markdown解码器基于深度优先递归解码, 正常情况下对于嵌套了其他PowerEditor
节点的根节点, 你无需考虑其内部的解码方式, 因为它们将遵照默认解码函数进行解码。
你只需要考虑自定义节点的渲染行为即可, 并且可以通过编写不同的解码函数来一个个地对某一节点进行解码。
以下是一种自定义Markdown
解码器的实现方式:
- 对于某一节点, 如(
blockquote
):
> 这是一级引用
>> 这是二级引用
>>> 这是三级引用
blockquote(node, flags) {
const { blockquote: level } = flags;
let prefix = '';
for (let i = 0; i < level; i++) {
prefix += `>`;
}
return `\n${prefix} `;
}
函数名blockquote
必须与节点名相同, 且必须返回一个字符串或对象, 当返回对象时, 该对象包含prefix
和suffix
两个属性, 分别代表标记的前缀和后缀。
在PowerEditor
中blockquote
节点包含了子节点paragraph
及其下属的text
, 然而你不需要考虑非自定义子节点的解码方式, 因为它们将遵照默认解码函数进行解码。
因此在上述样例中你会发现函数仅实现了>
标记的渲染。然而需要注意的是, 对于不同级别的blockquote
在PowerEditor
中其level
属性是未知的, 因此你需要通过flags
参数来获取其level
属性。
flags
代表了当前节点的父节点是否为某一节点, 默认情况下flags
的所有属性均为false
, 在深度遍历中,一旦该节点为flags
中包含的节点, 则该节点属性将被设置为1
, 若该节点的子节点为flags
中包含的节点, 则该子节点属性将被设置为2
, 以此类推。
以下是Decoder
中包含的默认flags
, 你可以自行加入新的flags
属性
flags = {
inline: false,
inlineWrapper: false,
heading: false,
bulletList: false,
orderedList: false,
blockquote: false,
powerTaskItem: false,
powerTaskList: false,
tableHeader: false,
tableCell: false,
tableRow: false,
table: false
}
通过属性传入PowerEditor
:
<power-editor :mdDecNodeFuncsPlugins="mdDecNodeFuncsPlugins" :mdFlags="mdFlags"></power-editor>
data () {
return {
mdDecNodeFuncsPlugins: {
blockquote: (node, flags) => {
const { blockquote: level } = flags;
let prefix = '';
for (let i = 0; i < level; i++) {
prefix += `>`;
}
return `\n${prefix} `;
}
},
mdFlags: {
blockquote: false
}
}
}
- 对于某一标记, 如(
color
):
<font color="red">这是红色字体</font>
textStyle(text, mark) {
const { color } = mark.attrs;
return {
prefix: `<font color="${color}">`,
suffix: `</font>`
};
}
标记同样也是遵循标记名等于函数名的规则, 且必须返回一个字符串或对象, 当返回对象时, 该对象包含prefix
和suffix
两个属性, 分别代表标记的前缀和后缀。
传入方式同节点函数一致。
# 3. ImgInterceptor
你可以通过imgInterceptor
函数对图片中的数据进行后置处理, 以实现自定义的图片上传功能。当创建图片时或图片中的数据发生变化时, 该函数将被触发。
该函数接收一个包含以下函数的对象:
- showStatus: 显示状态函数, 包含一个参数
status
, 用于控制是否显式状态- param:
status
-true
表示显示状态,false
表示隐藏状态 - return:
undefined
- param:
- updateStatus: 更新状态函数, 依次包含
loading
,progress
,info
三个参数, 其中loading
表示是否显式加载状态,progress
表示加载进度,info
表示加载信息- param:
loading
-true
表示显示加载状态,false
表示隐藏加载状态 - param:
progress
- 加载进度, 为0-100
之间的数字 - param:
info
- 加载信息, 为字符串 - return:
undefined
- param:
- getImage: 获取图片函数, 用于获取图片中的
src
- return:
src
- 图片src
- return:
- interceptImage: 拦截图片函数, 包含一个参数
replaceSrc
, 用于在加载过程中替换图片中的src
, 并返回图片原始src
- param:
replaceSrc
- 用于替换图片中的src
- return:
src
- 图片原始src
- param:
- updateImage: 更新图片函数, 包含一个参数
src
, 用于更新图片中的src
- param:
src
- 用于更新图片中的src
- return:
undefined
- param:
- updateLock: 更新锁函数, 包含一个参数
lock
, 用于判断拦截器是否被锁定, 需要手动调用, 默认为true
表示未锁定- param:
lock
-true
表示锁定,false
表示解锁 - return:
undefined
- param:
同时, 该函数包含以下节点对象:
- node: 当前节点对象
- extension: 当前节点扩展对象
- getPos: 获取当前节点位置函数
- updateAttributes: 更新属性函数
- deleteNode: 删除节点函数
let imgInterceptor = ({
node,
extension,
getPos,
updateAttributes,
deleteNode,
showStatus,
updateStatus,
interceptImage,
updateImage,
updateLock
}) => {
// 你的代码
}