50 строк кода с использованием текстового редактора wangEditor в Vue3

JavaScript Vue.js

предисловие

В этой статье используетсяwangEditor V5Реализовать редактор Vue3. wangEditor V5Официально предоставленоVue-компоненты, очень прост в использовании.

wangEditor V5 проходит публичное тестирование, любые вопросы и предложения можно отправлять наgithub issue.

[Примечание] Редактор может продолжать обновляться в будущем, а API и конфигурация могут быть скорректированы. Поэтому, пожалуйста, зайдите вовремяДокументация, не полагайтесь исключительно на эту статью.

Установить

Инициализируйте среду Vue3 с помощью vue-cli, затем установите

yarn add @wangeditor/editor @wangeditor/editor-for-vue@next
yarn add lodash.clonedeep # 也可以使用其他 clonedeep 函数,能实现深拷贝即可

Создать редактор

написать код

определить компонентMyEditor.vue, код показан ниже. Около 50 рядов, логика очень проста. (Исходный код в статье последним)

<script setup>
import { onBeforeUnmount } from 'vue'
import { Editor, Toolbar, getEditor, removeEditor } from '@wangeditor/editor-for-vue'

// 定义一个编辑器 id ,要求:全局唯一且不变!!!
const editorId = 'wangeEditor-1'

// 编辑器配置
const editorConfig = {
    placeholder: '请输入内容...',
    MENU_CONF: { /* 菜单配置,下文解释 */ }
}

// 回调函数
const handleChange = (editor) => {
    console.log('change:', JSON.stringify(editor.children))
}

// 组件销毁时,及时销毁编辑器
onBeforeUnmount(() => {
    const editor = getEditor(editorId)
    if (editor == null) return

    // 销毁,并移除 editor
    editor.destroy()
    removeEditor(editorId)
})
</script>

<template>
    <div style="border: 1px solid #ccc">
        <!-- 工具栏 -->
        <Toolbar
            :editorId="editorId"
            style="border-bottom: 1px solid #ccc"
        />
        <!-- 编辑器 -->
        <Editor
            :editorId="editorId"
            :defaultConfig="editorConfig"
            @onChange="handleChange"
            style="height: 500px"
        />
    </div>
</template>

<!-- 别忘了引入样式 -->
<style src="@wangeditor/editor/dist/css/style.css"></style>

бегать

ПучокMyEditor.vueпознакомился сApp.vueдля создания полнофункционального редактора.
Когда содержимое изменится, оно будет запущено в режиме реального времени.handleChangeфункция.

image.png

Меры предосторожности

  • идентификатор редактораeditorIdЧтобы быть глобально уникальным, без дублирования, без изменений
  • Когда компонент Vue будет уничтожен, вовремя уничтожьте редактор

установить содержание

Формат JSON и формат HTML, выберите один из них.

установить JSON

При создании редактора вы можете использоватьdefaultContent 设置初始化 JSON 内容。 Уведомление,defaultContentнуждаться вcomputedСредняя и глубокая копия, иначе будет сообщено об ошибке.

Содержимое JSON передается черезeditor.childrenполученный.

<script setup>
import { computed } from 'vue'
import cloneDeep from 'lodash.clonedeep'

// 编辑将默认显示的内容
const defaultContent = [
    {
        type: "paragraph",
        children: [{ text: "hello world" }],
    },
]
const getDefaultContent = computed(() => cloneDeep(defaultContent)) // 注意,深拷贝

// 其他...

</script>

<template>
    <div style="border: 1px solid #ccc">
        <Toolbar .../>
        <Editor
            :defaultContent="getDefaultContent" <!-- 注意,这里引入的是 computed 返回值 -->
            // 其他...
        />
    </div>
</template>

установить HTML

Когда редактор инициализируется, его можноdefaultHtmlУстановите содержимое HTML по умолчанию. HTML-контент передается черезeditor.getHtml()полученный.

【Особое внимание】ЗдесьdefaultHtmlОн может распознавать только вывод в формате HTML с помощью wangEditor (т.е.editor.getHtml()возвращаемый HTML-контент).Поскольку формат HTML слишком гибкий, wangEditor не может распознать их все. Например:

  • wangEditor может распознать<strong>hello</strong>выделено жирным шрифтом, но не распознано<span style="font-weight: bold;">hello</span>.
  • wangEditor не может быть правильно проанализирован<div>xxx</div>, потому что wangEditor не выводит HTML<div>.
<script setup>
const defaultHtml = '<p>hello&nbsp;<strong>world</strong></p>'

// 其他...
</script>

<template>
    <div style="border: 1px solid #ccc">
        <Toolbar .../>
        <Editor
            :defaultHtml="defaultHtml"
            // 其他...
        />
    </div>
</template>

Ajax асинхронно извлекает содержимое, а затем создает редактор

используя Vue3refопределитьflagПеременная. После того, как ajax получит содержимое асинхронно, измените егоdefaultContent(илиdefaultHtml) а такжеflag.

// defaultContent (JSON 格式) 和 defaultHtml (HTML 格式) 二选一
const defaultContent = ref([])
const getDefaultContent = computed(() => cloneDeep(defaultContent.value))

const defaultHtml = ref('')

const flag = ref(false)

// 模拟 ajax 异步获取内容
setTimeout(() => {
    defaultContent.value =  [
        {
            type: "paragraph",
            children: [{ text: "ajax 异步获取的内容" }],
        },
    ]
    defaultHtml.value = '<p>ajax&nbsp;异步获取的内容</p>'
    
    flag.value = true
}, 2000)

затем согласноflagОпределяет, отображать ли редактор.

<template>
    <div style="border: 1px solid #ccc" v-if="flag">
        <!-- 工具栏 -->
        <Toolbar .../>
        <!-- 编辑器 -->
        <Editor .../>
    </div>
</template>

настроить

Конфигурация редактора

Приведенный выше код настраивает толькоplaceholderНапример. Он также поддерживаетreadOnly autoFocus maxLengthи другие конфигурации, см.Документация.

// 编辑器配置
const editorConfig = {
    placeholder: '请输入内容...',
    // 可继续其他配置...
    
    MENU_CONF: { /* 菜单配置,下文解释 */ }
}

Но обратите внимание,Все функции обратного вызова в этом документе не могут быть переданы в виде конфигурации,Такие какonCreated onChange onDestroyedЖдать. Эти функции обратного вызоваДолжен передаваться как событие Vue.

<Editor
    :editorId="editorId"
    :defaultConfig="editorConfig"
    :defaultContent="getDefaultContent"
    :defaultHtml="defaultHtml"
    style="height: 500px"
    
    <!-- 回调函数,以 Vue 事件形式 -->
    @onCreated="handleCreated"
    @onChange="handleChange"
    @onDestroyed="handleDestroyed"
    @onFocus="handleFocus"
    @onBlur="handleBlur"
    @customAlert="customAlert"
    @customPaste="customPaste"
  />

Конфигурация панели инструментов

Вы можете использовать эту конфигурацию, если хотите изменить меню панели инструментов, например, скрыть определенные меню, переупорядочить группы. служба поддержкиtoolbarKeysа такжеexcludeKeys, вы можете обратиться кДокументация.

// 工具栏配置
const toolbarConfig = {
    toolbarKeys: [ /* 显示哪些菜单,如何排序、分组 */ ],
    excludeKeys: [ /* 隐藏哪些菜单 */ ],
}
<Toolbar
    :editorId="editorId"
    :defaultConfig="toolbarConfig" <!-- 传入配置 -->
    style="border-bottom: 1px solid #ccc"
/>

конфигурация меню

Если вы хотите настроить меню, например, настроить цвет, шрифт, размер шрифта, настроить адрес API для загрузки изображений и т. д., вы можете использовать настройку меню. конкретная ссылкаДокументация.

// 编辑器配置
const editorConfig = {
    // 某些编辑器配置,如 placeholder
    
    // 所有的菜单配置,都要在 MENU_CONF 属性下
    MENU_CONF: {
        // 配置字号
        fontSize: [ ... ],
        
        // 配置上传图片
        uploadImage: { ... },
        
        // 继续其他菜单配置
    }
}

API

wangEditor предоставляет богатый API, который может помочь вам с любой операцией редактора. Может относиться кДокументация.

  • Настройка связанных API
  • API, связанные с обработкой контента
  • API, связанные с операциями узла
  • API, связанные с операциями выбора
  • API для пользовательских событий

После создания редактора можно пройтиgetEditor(editorId)Получатьeditorэкземпляр, а затем выполнить API.

onBeforeUnmount(() => {
    const editor = getEditor(editorId) // 获取 editor 实例
    if (editor == null) return

    editor.destroy() // 执行 API
})

получить контент

получить HTML

пройти черезeditor.getHtml()Получить HTML-контент.

получить JSON

пройти черезeditor.childrenПолучите содержимое JSON.

Формат JSON можно преобразовать в формат HTML, который поддерживает браузеры и nodejs. Если он есть в nodejs, его нужно установитьyarn add jsdom global-jsdom, и представитьrequire('global-jsdom/register').

import { createEditor } from '@wangeditor/editor'

const editor = createEditor({ content }) // `content` 即 JSON 内容
const html = editor.getHtml()

Суммировать

Весь исходный код этой статьи находится вздесь.

wangEditor V5 проходит публичное тестирование, любые вопросы и предложения можно отправлять наgithub issue.