React SimpleMDE Markdown Editor,支持 Emoji 表情

React SimpleMDE Markdown Editor

特性

  • 支持粘贴和拖拽上传图片。
  • 支持自定义预览渲染
  • 支持emoji表情

安装

npm install -S yt-simplemde-editor

使用

您可以在 demo 中查看基本用法。

Demo

git clone https://github.com/yanthink/react-simplemde-editor
cd react-simplemde-editor
npm install
npm run build
npm link

cd demo
npm install
npm link yt-simplemde-editor
npm start

API

参数 说明 类型 默认值
id 编辑器id string -
className 根元素的类名称 string -
label label string -
uploadOptions 上传附件参数 UploadOptions -
theme 主题设置 string -
getMdeInstance 获取编辑器实例方法 simplemde => void -
extraKeys 快捷键设置,详见 extraKeys object -
value 初始化内容 string -
onChange 内容发生改变时触发 value => void -
options SimpleMDE选项 object -
emoji emoji参数 Emoji -

UploadOptions

参数 说明 类型 默认值
action 上传的地址 string
name 发到后台的文件参数名 string file
jsonName 后台响应的文件地址名称 string fileUrl
allowedTypes 接受上传的文件类型 string | array image/*
progressText 上传中显示内容 string ![Uploading file...]()
data 上传所需参数 object | file => object -
headers 设置上传的请求头部 object -
withCredentials 上传请求时是否携带 cookie boolean false
beforeUpload 上传文件之前的钩子,参数为上传的文件,若返回 false 则停止上传 (file) => boolean | Promise -
onSuccess 上传成功事件 (response, file) => any -
onError 上传失败事件 (err, response, file) => any -

Emoji

参数 说明 类型 默认值
enabled 是否开启 boolean false
autoComplete 是否开启 shortname 自动补全 boolean false
insertConvertTo 插值转换,可选值 shortnameunicode string shortname

效果图:

React SimpleMDE Markdown Editor,支持 Emoji 表情

React SimpleMDE Markdown Editor,支持 Emoji 表情

React SimpleMDE Markdown Editor,支持 Emoji 表情

React SimpleMDE Markdown Editor,支持 Emoji 表情

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 11

请问为什么拖拽的图片返回的地址

file
是这样的?

file

5年前 评论

@zhangzijian markdown 图片就是这种格式的,你可以点击预览看效果。
还有 jsonFieldName 这个字段得根据你 uploadUrl 响应的数据结构来设置

5年前 评论

上传图片可不可以支持上传本地图片,就是那种常规上传的样式?

4年前 评论
yanthink (楼主) 4年前

@yujian2018
本地上传需要自己实现,这里提供一个以前写的 demo 给你参考下

import React, { PureComponent, Fragment } from 'react';
import cookie from 'cookie';
import SimpleMDEEditor from 'yt-simplemde-editor';
import marked from 'marked';
import Prism from 'prismjs';
import { Modal, Button, Upload, Icon } from 'antd';
import 'antd/dist/antd.css'

// 图片上传地址
const uploadUrl = '/api/attachment/upload';

const progressText = '![Uploading file {uid}...]()';

const urlText = '![file]({filename})';

class App extends PureComponent {
  state = {
    value: '',
    uploadVisible: false,
  };

  renderMarkdown = text => {
    const html = marked(text, { breaks: true });
    if (/language-/.test(html)) {
      const container = document.createElement('div');
      container.innerHTML = html;
      Prism.highlightAllUnder(container);
      return container.innerHTML;
    }

    return html;
  };

  render () {
    const { uploadVisible } = this.state;

    const editorProps = {
      value: this.state.value,
      getMdeInstance: simplemde => {
        this.simplemde = simplemde;
      },
      onChange: (value) => {
        this.setState({ value })
      },
      options: {
        // see https://github.com/sparksuite/simplemde-markdown-editor#configuration
        spellChecker: false,
        forceSync: true,
        autosave: {
          enabled: true,
          delay: 5000,
          uniqueId: 'article_content',
        },
        renderingConfig: {
          // codeSyntaxHighlighting: true,
        },
        previewRender: this.renderMarkdown, // 自定义预览渲染
        tabSize: 4,
        toolbar: [
          'bold',
          'italic',
          'heading',
          '|',
          'quote',
          'code',
          'table',
          'horizontal-rule',
          'unordered-list',
          'ordered-list',
          '|',
          'link',
          {
            name: 'image',
            action: () => {
              this.setState({ uploadVisible: true })
            },
            className: 'fa fa-image',
            title: '上传图片',
          },
          '|',
          'side-by-side',
          'fullscreen',
          '|',
          {
            name: 'guide',
            action () {
              const win = window.open(
                'https://github.com/riku/Markdown-Syntax-CN/blob/master/syntax.md',
                '_blank',
              );
              if (win) {
                // Browser has allowed it to be opened
                win.focus();
              }
            },
            className: 'fa fa-info-circle',
            title: 'Markdown 语法!',
          },
        ],
      },
      uploadOptions: {
        action: uploadUrl,
        jsonName: 'data.fileUrl',
        headers: {
          Accept: 'application/x.sheng.v1+json',
          'X-XSRF-TOKEN': cookie.parse(document.cookie)['XSRF-TOKEN'],
        },
      },
    };

    const modalProps = {
      title: '插入图片',
      visible: uploadVisible,
      footer: null,
      centered: true,
      onCancel: () => {
        this.setState({ uploadVisible: false });
      },
    };

    const uploadProps = {
      action: uploadUrl,
      name: 'file',
      multiple: true,
      showUploadList: false,
      beforeUpload: file => {
        const text = progressText.replace('{uid}', file.uid);
        this.simplemde.codemirror.replaceSelection(text);
        file.insertText = text;
      },
      headers: {
        Accept: 'application/x.sheng.v1+json',
        'X-XSRF-TOKEN': cookie.parse(document.cookie)['XSRF-TOKEN'],
      },
      data: {
        token: '', // todo token
      },
      onChange: ({ file }) => {
        if (file.status === 'done') {
          const { response: { data }, originFileObj } = file;
          const { filename } = data;
          const cursor = this.simplemde.codemirror.codemirror.getCursor();
          const newValue = urlText.replace('{filename}', filename);
          const text = this.simplemde.codemirror.getValue().replace(originFileObj.insertText, newValue);
          this.simplemde.codemirror.setValue(text);
          cursor.ch += newValue.length - progressText.length;
          this.simplemde.codemirror.setCursor(cursor);
          this.simplemde.codemirror.focus();
          originFileObj.insertText = newValue;
        }

        this.setState({ uploadVisible: false });
      },
    };

    return (
      <Fragment>
        <SimpleMDEEditor {...editorProps} />
        <Modal
          {...modalProps}
        >
          <Upload {...uploadProps}>
            <Button type="primary">
              <Icon type="upload" /> 点击上传
            </Button>
          </Upload>
        </Modal>
      </Fragment>
    )
  }
}

export default App;
4年前 评论

你好,源代码仓库yt-simplemde-editor 按照readme在demo中执行npm install 时报错, emoji-assets包出错

4年前 评论

@yujian2018
emoji-assets 这个包之前在 npm 的版本是4.5,所以我用了 git 地址,这个项目比较大,所以install时可能会比较慢。
现在 npm 已经更新到 5.0.2 了,你可以修改 demo/package.json 文件:

{
  ...
  "dependencies": {
    "emoji-assets": "^5.0.2",
    ...
  }
  ...
}

然后在用淘宝镜像 cnpm install

4年前 评论
yujian2018 4年前
yanthink (作者) (楼主) 4年前
yanthink (作者) (楼主) 4年前

@yujian2018
你也可以不用emoji-assets包,emoji-toolkit 会默认使用 CDN(jsdelivr)地址。

4年前 评论
maliao

不错,给你个start

4年前 评论
yanthink (楼主) 4年前

而且下载你的demo 运行报错

file

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!