基于tiptap自定义编辑器

大体实现功能有:

主功能功能扩展备注
TiptapEditor1.单人编辑
2.协作编辑
3.插件开发(参考element-tiptap/tiptap官网)
tiptap编辑器功能及部分插件功能引入
CustomEditorRender1.表头固定
2.自适应表格宽度
3.代码高亮
4.生成目录
自定义富文本内容渲染CustomEditorRender
新增部分hook
ContentDiff 富文本对比
Mark 富文本内容划词评论

CustomEditor主要由TiptapEditor、CustomEditorRender两部分,根据当前的编辑状态区分,demo如下:

<template>
    <div v-if="isEditable" class="editable-description">
    <slot name="editable-description-header"></slot>
    <tiptap-editor
      ref="tEditor"
      :collaboration-options="collaborationOptions"
      :placeholder="placeholder"
      class="custom-editor tiptap-editable-content"
      :content="editorContent"
      :page-unload-interrupt="pageUnloadInterrupt"
      @change-contents="changeContents"
      @save-content="saveContent"
    >
      <template #draft="{ editor }">
        <slot name="draft" :editor="editor"></slot>
      </template>
    </tiptap-editor>
  </div>
  <div v-else class="uneditable">
    <slot name="uneditable-description-header"></slot>
    <slot name="uneditable-editor-renderer">
      <y-editor-renderer :id="editorId" :content="editorContent"></y-editor-renderer>
    </slot>
  </div>
</template>
import { CollaborationOptions, OutputContents } from '@/components/tiptapEditor/editor'
const props = withDefaults(
  defineProps<{
    isEditorUseful: boolean
    editorContent: string
    collaborationOptions?: CollaborationOptions
    parentDynamicHeight?: boolean
    editorId?: string
    placeholder?: string
    pageUnloadInterrupt?: boolean
  }>(),
  {
    editorId: 'demand-editor',
    parentDynamicHeight: false,
  },
)

const {
  isEditorUseful: isEditable,
  editorContent,
  collaborationOptions,
  editorId,
  placeholder,
  pageUnloadInterrupt,
  parentDynamicHeight,
} = toRefs(props)

const emits = defineEmits([
  'changeContents',
  'handleEditorClick',
  'update:editorContent',
  'saveContent',
])

const tEditor = ref<{
  clearContent: () => void
  insertContent: (content: string) => void
  focusEditor: () => void
  destroyWs: () => void
}>()
const changeContents = (content: OutputContents) => {
  emits('update:editorContent', content.content)
  emits('changeContents', content) //对象
}

const saveContent = () => {
  isEditable.value && emits('saveContent')
}

如果需用调用编辑器内部api,使用vue3的defineExpose即可


愚者
12 声望3 粉丝