Kun

Kun

IT学徒、技术民工、斜杠青年,机器人爱好者、摄影爱好 PS、PR、LR、达芬奇潜在学习者


共 279 篇文章


quill.js

Draft.js

braft-editor

富文本编辑器

安装

# 使用npm安装
npm install braft-editor --save

# 使用yarn安装
yarn add braft-editor

使用

import BraftEditor from 'braft-editor'
// 定义一段HTML字符串
const htmlString = `<p>Hello <b>World!</b></p>`
// 将HTML字符串转换为编辑器所需要的EditorState实例
const editorState = BraftEditor.createEditorState(htmlString)

//上面创建的变量editorState即可传给编辑器的value属性
render () {
    return (
        <BraftEditor value={editorState}/>
    )
}

实例属性

名称 说明
font-size 文字字号选择器
font-family 文字字体选择器
line-height 文字行高选择器
letter-spacing 文字字间距选择器
text-color 文字颜色选择器,包含文字背景颜色设置
bold 设置文字加粗
italic 设置文字斜体
underline 设置文字下划线
strike-through 设置文字删除线
superscript 设置文字为上标
subscript 设置文字为下标
remove-styles 清除文字样式
emoji Emoji表情选择器
text-align 文字对齐方式工具,可通过textAligns属性来指定可以使用哪些对齐方式
text-indent 段落缩进工具,最多可缩进6级
link 链接插入工具
headings 段落类型(标题1-6、常规)
list-ul 无序列表
list-ol 有序列表
blockquote 引用段落
code 代码块
hr 水平线工具
media 多媒体插入工具
clear 内容清除工具
undo 撤销操作
redo 重做操作
separator 分割线,连续的多个separator将只显示为1个

braft-extension

https://github.com/margox/braft-extensions

braft-editor的拓展模块

比如文字高亮

import 'braft-editor/dist/index.css'
import 'braft-extensions/dist/code-highlighter.css'

import BraftEditor from 'braft-editor'
import CodeHighlighter from 'braft-extensions/dist/code-highlighter'

const options = {
  includeEditors: ['editor-id-1'], // 指定该模块对哪些BraftEditor生效,不传此属性则对所有BraftEditor有效
  excludeEditors: ['editor-id-2']  // 指定该模块对哪些BraftEditor无效
}

BraftEditor.use(CodeHighlighter(options))

braft-utils

https://github.com/margox/braft-utils

Braft-editor的工具包

包括把html解析成字符串、插入html等

tinymce

支持在react、vue、angular中插入富文本

安装

npm install --save @tinymce/tinymce-react

使用

import React, { useRef } from 'react';
import { Editor } from '@tinymce/tinymce-react';

export default function App() {
  const editorRef = useRef(null);
  const log = () => {
    if (editorRef.current) {
      console.log(editorRef.current.getContent());
    }
  };
  return (
    <>
      <Editor
        apiKey='your-api-key'
        onInit={(evt, editor) => editorRef.current = editor}
        initialValue="<p>This is the initial content of the editor.</p>"
        init={{
          height: 500,
          menubar: false,
          plugins: [
            'advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'preview',
            'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen',
            'insertdatetime', 'media', 'table', 'code', 'help', 'wordcount'
          ],
          toolbar: 'undo redo | blocks | ' +
            'bold italic forecolor | alignleft aligncenter ' +
            'alignright alignjustify | bullist numlist outdent indent | ' +
            'removeformat | help',
          content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }'
        }}
      />
      <button onClick={log}>Log editor content</button>
    </>
  );
}

slate

Slate 是一个使用 TypeScript 开发的富文本编辑器开发框架,诞生于 2016 年,作者是 Ian Storm Taylor。它吸收了 QuillProsemirrorDraft.js 的优点,核心数据模型十分精简,具有高度的可扩展性

特点:

  • 插件作为一等公民,能够完全修改编辑器行为
  • 数据层和渲染层分离,更新数据触发渲染
  • 文档数据类似于 DOM 树,可嵌套
  • 具有原子化操作 API,理论上支持协同编辑
  • 使用 React 作为渲染层
  • 不可变数据结构 Immer

使用

// Import React dependencies.
import React, { useState } from 'react'
// Import the Slate editor factory.
import { createEditor } from 'slate'

// Import the Slate components and React plugin.
import { Slate, Editable, withReact } from 'slate-react'

const initialValue = [
  {
    type: 'paragraph',
    children: [{ text: 'A line of text in a paragraph.' }],
  },
]

const App = () => {
  // Create a Slate editor object that won't change across renders.
  const [editor] = useState(() => withReact(createEditor()))
  return (
    // Add the editable component inside the context.
    <Slate editor={editor} initialValue={initialValue}>
      <Editable />
    </Slate>
  )
}

slate-history

Slate 插件,为编辑器提供 撤销 **和 **重做功能。

export const withHistory = <T extends Editor>(editor: T) => {
  const e = editor as T & HistoryEditor
  const { apply } = e
  e.history = { undos: [], redos: [] }

  e.redo = () => {
    /// ...
  }

  e.undo = () => {
    /// ...
  }

  e.apply = (op: Operation) => {
    /// ...
  }

  return e
}

slate-hyperscript

是一个使用 JSX 编写 Slate 文档的 hyperscript 工具

lexical

facebook出品的富文本框

安装

npm install --save lexical @lexical/react

使用

import {$getRoot, $getSelection} from 'lexical';
import {useEffect} from 'react';

import {LexicalComposer} from '@lexical/react/LexicalComposer';
import {PlainTextPlugin} from '@lexical/react/LexicalPlainTextPlugin';
import {ContentEditable} from '@lexical/react/LexicalContentEditable';
import {HistoryPlugin} from '@lexical/react/LexicalHistoryPlugin';
import {OnChangePlugin} from '@lexical/react/LexicalOnChangePlugin';
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
import {LexicalErrorBoundary} from '@lexical/react/LexicalErrorBoundary';

const theme = {
  // Theme styling goes here
  // ...
}

// When the editor changes, you can get notified via the
// LexicalOnChangePlugin!
function onChange(editorState) {
  editorState.read(() => {
    // Read the contents of the EditorState here.
    const root = $getRoot();
    const selection = $getSelection();

    console.log(root, selection);
  });
}

// Lexical React plugins are React components, which makes them
// highly composable. Furthermore, you can lazy load plugins if
// desired, so you don't pay the cost for plugins until you
// actually use them.
function MyCustomAutoFocusPlugin() {
  const [editor] = useLexicalComposerContext();

  useEffect(() => {
    // Focus the editor when the effect fires!
    editor.focus();
  }, [editor]);

  return null;
}

// Catch any errors that occur during Lexical updates and log them
// or throw them as needed. If you don't throw them, Lexical will
// try to recover gracefully without losing user data.
function onError(error) {
  console.error(error);
}

function Editor() {
  const initialConfig = {
    namespace: 'MyEditor',
    theme,
    onError,
  };

  return (
    <LexicalComposer initialConfig={initialConfig}>
      <PlainTextPlugin
        contentEditable={<ContentEditable />}
        placeholder={<div>Enter some text...</div>}
        ErrorBoundary={LexicalErrorBoundary}
      />
      <OnChangePlugin onChange={onChange} />
      <HistoryPlugin />
      <MyCustomAutoFocusPlugin />
    </LexicalComposer>
  );
}

https://mp.weixin.qq.com/s/7DM8_HrcAwrOzJGyljgriw

prosemirror-view

https://github.com/ProseMirror/prosemirror-view

网页图片编辑

photopea

https://github.com/photopea/photopea

https://github.com/photopea/UPNG.js

如果你觉得我的文章对你有帮助的话,希望可以推荐和交流一下。欢迎關注和 Star 本博客或者关注我的 Github