当前位置: 首页 > 工具软件 > tiptap > 使用案例 >

基于vue的tiptap编辑器插件(三)

狄凯
2023-12-01

美化编辑器

        前面介绍过,tiptap是一个headless的编辑器,所以他自己是没有样式的,我们需要手动给他添加一些样式。文档中介绍了三种美化编辑器的方式,听我一一道来。

Option 1: Style the plain HTML

        整个编辑器都是被一个class为ProseMirror的div所包裹,所以你可以直接在样式表中对class为ProseMirror的样式进行修饰。比如:

/* Scoped to the editor */
.ProseMirror p {
  margin: 1em 0;
}

Option 2: Add custom classes

        你可以自定义一些class,然后将这些class通过配置项载入到对应扩展或editor本身中。如果是editor本身,则如下所示

new Editor({
  editorProps: {
    attributes: {
      class: 'prose prose-sm sm:prose lg:prose-lg xl:prose-2xl mx-auto focus:outline-none',
    },
  },
})

如果是一些扩展,如下所示

new Editor({
  extensions: [
    Document,
    Paragraph.configure({
      HTMLAttributes: {
        class: 'my-custom-paragraph',
      },
    }),
    Heading.configure({
      HTMLAttributes: {
        class: 'my-custom-heading',
      },
    }),
    Text,
  ],
})

Option 3: Customize the HTML

        你也可以在原来扩展的基础上做一些样式上的修改,成为一个新的扩展

import Bold from '@tiptap/extension-bold'

const CustomBold = Bold.extend({
  renderHTML({ HTMLAttributes }) {
    // Original:
    // return ['strong', HTMLAttributes, 0]
    return ['b', HTMLAttributes, 0]
  },
})

new Editor({
  extensions: [
    // …
    CustomBold,
  ],
})

        这三种方式,我比较推荐第二种,一方面这种配置的方式比较灵活,另一方面,可以操作到node上,比第一种方式更精细也不容易出错。

输出

        这一节主要讲,如何将编辑器里的内容转化为json字符串或者html字符串存储起来,以及如何把这两种格式的字符串传给编辑器并呈现内容。

导出字符串

        如何得到当前编辑器文本内容的json字符串?

        const json = editor.getJSON()

        同理对于html字符串:

        const html = editor.getHTML()

        如何将json字符串传给编辑器并显示内容?

        首先,你要知道,getJSON()返回的json字符串是类似以下的格式:

{
  "type": "doc",
  "content": [
    {
      "type": "paragraph",
      "content": [
        {
          "type": "text",
          "text": "Wow, this editor instance exports its content as JSON."
        }
      ]
    }
  ]
}

符合这样的格式,且最外层的"type"为"doc",那么将该字符串content传入以下方法

editor.commands.setContent(content)

同理对于html字符串

editor.commands.setContent(`<p>Example Text</p>`)

监听改变

        如果你想监听内容的改变,那么可以这么做

const editor = new Editor({
  // intial content
  content: `<p>Example Content</p>`,

  // triggered on every change
  onUpdate: ({ editor }) => {
    const json = editor.getJSON()
    // send the content to an API here
  },
})

HTML与JSON格式的转换

        在某些场景下,需要对内容的格式进行转换。比如,用户在web端的某个tiptap编辑器内写了内容并以json格式保存至远程服务器中,而远程服务器需要根据这段内容生成html并返回,那么就需要用到这个功能。

JSON转HTML

<template>
  <pre><code>{{ output }}</code></pre>
</template>

<script>
// Option 1: Browser + server-side
import Bold from '@tiptap/extension-bold'
// Option 2: Browser-only (lightweight)
// import { generateHTML } from '@tiptap/core'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { generateHTML } from '@tiptap/html'

const json = {
  type: 'doc',
  content: [
    {
      type: 'paragraph',
      content: [
        {
          type: 'text',
          text: 'Example ',
        },
        {
          type: 'text',
          marks: [
            {
              type: 'bold',
            },
          ],
          text: 'Text',
        },
      ],
    },
  ],
}

export default {
  computed: {
    output() {
      return generateHTML(json, [
        Document,
        Paragraph,
        Text,
        Bold,
        // other extensions …
      ])
    },
  },
}
</script>

显示结果:<p>Example <strong>Text</strong></p>

HTML转JSON

<template>
  <pre><code>{{ output }}</code></pre>
</template>

<script>
// Option 1: Browser + server-side
import Bold from '@tiptap/extension-bold'
// Option 2: Browser-only (lightweight)
// import { generateHTML } from '@tiptap/core'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { generateHTML } from '@tiptap/html'

const json = {
  type: 'doc',
  content: [
    {
      type: 'paragraph',
      content: [
        {
          type: 'text',
          text: 'Example ',
        },
        {
          type: 'text',
          marks: [
            {
              type: 'bold',
            },
          ],
          text: 'Text',
        },
      ],
    },
  ],
}

export default {
  computed: {
    output() {
      return generateHTML(json, [
        Document,
        Paragraph,
        Text,
        Bold,
        // other extensions …
      ])
    },
  },
}
</script>

显示结果:<p>Example <strong>Text</strong></p>

 类似资料: