2.0.7 • Published 1 month ago

@qingbing/ts-v3-md-editor v2.0.7

Weekly downloads
-
License
MIT
Repository
-
Last release
1 month ago

MdEditor 插件介绍

1. 概要说明

1.1 地址

https://gitee.com/duqingbing/ts-v3-package/tree/ts-v3-md-editor

1.2 插件描述

vite + ts + vue3 二次封装 md-editor-v3 出来的 MdEditor 编辑器

1.3 重要依赖

  • @qingbing/ts-v3-utils: ^2.0.15"
  • md-editor-v3: ^4.12.2"
  • vue: ^3.4.21"

1.4 插件安装

# yarn 安装
yarn add @qingbing/ts-v3-md-editor

# npm 安装
npm i @qingbing/ts-v3-md-editor

2. MdPreview 说明

2.1 属性说明

属性名类型是否必需默认值意义
confObject{ theme: 'light', showCodeRowNumber: true }预览配置
  • conf 内部属性说明(主要参考 md-editor-v3)
属性名类型默认值意义
modelValuestring''编辑内容,可使用 v-model="value" 实现双向绑定
theme'light''dark''light'主题
classstring''编辑器最外层样式
languagestring'zh-CN'内置中英文('zh-CN','en-US')
previewThemeTMdEditorPreviewTheme'default'预览内容主题
editorIdstring'md-editor-v3'编辑器唯一标识,非必须,防止产生服务端与客户端渲染内容不一致错误提示,以及单页面多编辑器时做区别
showCodeRowNumberbooleanfalse代码块显示行号
stylestring \ CSSProperties''编辑器内联样式
noMermaidbooleanfalse不希望使用图表展示内容,可以设置关闭
noKatexbooleanfalse不希望使用数学公式展示内容,可以设置关闭
codeThemeTMdEditorCodeTheme'atom'代码块高亮样式名称
noIconfontbooleantrue不插入 iconfont 链接,可以下载到本地自行引入
codeStyleReversebooleantrue在主题下的 light 模式上使用暗色系的代码风格
codeStyleReverseListArray'default', 'mk-cute'需要自动调整的预览主题
noHighlightbooleanfalse不高亮代码,也不会加载相应的扩展库
noImgZoomInbooleanfalse关闭编辑器默认的放大功能(^4.4.0)
customIconCustomIcon{}自定义的图标
sanitizeMermaid(h: string) => Promise(h: string) => Promise.resolve(h)转换生成的 mermaid 代码
mdHeadingId(text: string, level: number, index: number) => string(text) => text构造标题ID的生成方式
formatCopiedText(text: string) => string(text) => text格式化复制代码

2.2 事件说明, 主要参考 md-editor-v3

事件名类型意义
onHtmlChanged(h: string) => voidhtml 变化回调事件,用于获取预览 html 代码
onGetCatalog(list: HeadList[]) => void动态获取markdown目录

2.3 实例暴露说明

属性名类型
-

3. MdEditor 说明

3.1 属性说明

属性名类型是否必需默认值意义
confObject{ mode: "simple", theme: 'light', showCodeRowNumber: true }编辑器配置
  • conf 内部属性说明(主要参考 md-editor-v3), 拥有 MdPreview - conf 的所有属性
属性名类型默认值说明
modestring'simple'组件定义的编辑器模式,主要控制 toolbar
pageFullscreenbooleanfalse页面内全屏
previewbooleantrue是否显示预览
htmlPreviewbooleanfalse是否显示 html 预览。当设置为true时,需要将preview设置为false
toolbarsTMdEditorToolbarItem[]all选择性展示工具栏
toolbarsExcludeTMdEditorToolbarItem[][]选择性不展示工具栏
noPrettierbooleanfalse是否启用 prettier 优化 md 内容
tabWidthnumber2编辑器一个 TAB 键等于空格数
tableShapenumber, number6, 4标题栏添加表格时,预设待选表格大小,第一个代表最大列数,第二个代表最大行数
placeholderstring''啊这-_-!
footersArray<'markdownTotal''=''scrollSwitch'number>'markdownTotal', '=', 'scrollSwitch'页脚显示内容,'='左右分割,设置为[]不显示页脚
scrollAutobooleantrue同步滚动状态
noUploadImgbooleanfalse工具栏不显示上传图片入口
autoFocusbooleanfalse原生属性,文本区域自动获得焦点
disabledbooleanfalse原生属性,禁用文本区域
readOnlybooleanfalse原生属性,文本区域为只读
maxLengthnumber | 原生属性,文本区域允许的最大字符数
autoDetectCodebooleanfalse是否启用自动识别粘贴代码类别,目前仅支持从vscode复制的内容
showToolbarNamebooleanfalse是否在工具栏下面显示对应的文字名称
inputBoxWitdhstring50%输入框默认的宽度x
inputBoxWidthstring50%输入框默认的宽度x, 纠正组件单词错误

3.2 事件说明, 主要参考 md-editor-v3, 拥有 MdPreview 的所有属性

事件名类型意义
onChange(v: string) => void内容变化事件(当前与textarea的oninput事件绑定,每输入一个单字即会触发)
onSave(v: string, h: Promise) => void保存事件,快捷键与保存按钮均会触发
onUploadImg(files:Array,callBack:(urls:string[]Array<{url:string,alt:string,title:string}>) => void) => void上传图片事件,弹窗会等待上传结果,务必将上传后的 urls 作为 callback 入参回传
onError(err: { name: 'Cropper''fullscreen''prettier''overlength', message: string}) => void捕获执行错误事件,目前支持Cropper、fullscreen、prettier实例未加载完成操作,以及输入内容超出限制长度的错误
onBlur(event: FocusEvent) => void输入框失去焦点时触发事件
onFocus(event: FocusEvent) => void输入框获得焦点时触发事件
onInput(event: Event) => void输入框键入内容事件
onDrop(event: DragEvent) => void拖放内容事件
onInputBoxWitdhChange(width: string) => void调整输入框宽度事件
onInputBoxWidthChange(width: string) => void调整输入框宽度事件, 纠正组件单词错误

3.3 实例暴露说明

属性名类型
-

4. 示例

4.1 全局注册使用

  • 一旦注册, MdEditorMdPreview 作为组件全局通用
  • 使用方法参考 3.2 模板组件使用, 去掉组件导入的语句即可
// main.ts
import "@qingbing/ts-v3-md-editor/dist/style.css"
import { MdEditorPlugin } from '@qingbing/ts-v3-md-editor'
app.use(MdEditorPlugin)

4.2 模板组件使用

<template>
    <h1>Page</h1>
    <h2> editor</h2>
    <MdEditor v-model="text" :conf="mdEditorConf" />
    <MdEditor v-model="content" :conf="{ mode: 'mini' }" />
    <MdEditor v-model="content" :conf="{ mode: 'simple' }" />
    <MdEditor v-model="content" :conf="{ mode: 'normal' }" />
    <MdEditor v-model="content" />
    <hr>
    <MdPreview v-model="content" />
    <MdPreview v-model="content" :conf="mdPreviewConf" />
</template>
  
<script setup  lang="ts">
import 'md-editor-v3/lib/style.css'; // 编辑器样式
import 'md-editor-v3/lib/preview.css'; // 编辑器预览样式
import type { TMdEditorInnerError, TMdEditorProps, TMdEditorUploadImgCallBack, TMdPreviewProps } from "@qingbing/ts-v3-md-editor";
import { ref } from 'vue';
import { MdEditor, MdPreview } from "@qingbing/ts-v3-md-editor"; // 如果全局注册,这句直接删除

const mdEditorConf: TMdEditorProps = {
    mode: 'normal',
    // 内容变化事件(当前与textarea的oninput事件绑定,每输入一个单字即会触发)
    onChange: (v: string) => {
        console.log(v);
    },
    // 保存事件,快捷键与保存按钮均会触发
    onSave: (v: string, h: Promise<string>) => {
        console.log(v);
        h.then((html) => {
            console.log(html);
        });
    },
    // 上传图片事件,弹窗会等待上传结果,务必将上传后的 urls 作为 callback 入参回传
    onUploadImg: async (files: Array<File>, callback: TMdEditorUploadImgCallBack) => {
        const res = await Promise.all(
            files.map((file) => {
                return new Promise((rev, rej) => {
                    rev([
                        {
                            data: {
                                url: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'
                            }
                        },
                        {
                            data: {
                                url: 'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg'
                            }
                        },
                    ])
                    // const form = new FormData();
                    // form.append('file', file);
                    // axios
                    //     .post('/api/img/upload', form, {
                    //         headers: {
                    //             'Content-Type': 'multipart/form-data'
                    //         }
                    //     })
                    //     .then((res) => rev(res))
                    //     .catch((error) => rej(error));
                });
            })
        );
        // 方式一
        // callback(res.map((item) => item.data.url));
        callback(res.map((item) => 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'));

        // 方式二
        // callback(
        //     res.map((item: any) => ({
        //         url: item.data.url,
        //         alt: 'alt',
        //         title: 'title'
        //     }))
        // );
    },
    // 捕获执行错误事件,目前支持Cropper、fullscreen、prettier实例未加载完成操作,以及输入内容超出限制长度的错误
    onError: (err: TMdEditorInnerError) => {
        alert(err.message);
    },
    // 输入框失去焦点时触发事件
    onBlur: (event: FocusEvent) => {
        console.log('onBlur', event);
    },
    // 输入框获得焦点时触发事件
    onFocus: (event: FocusEvent) => { },
    // 输入框键入内容事件,
    onInput: (event: Event) => { },
    // 拖放内容事件
    onDrop: (event: DragEvent) => {
        event.stopPropagation();
        console.log('ee', event.dataTransfer?.files[0]);
    },
    // 调整输入框宽度事件
    onInputBoxWitdhChange: (width: string) => { },
}

const mdPreviewConf: TMdPreviewProps = {
    theme: 'dark',
    showCodeRowNumber: false
}
const content = ref("# title\n## sub title");
const text = ref("# Hello Editor\n```php\n$a = 5;\n$b = 6;\n$c = $a + $b\n```");
</script>
2.0.7

1 month ago

2.0.6

1 month ago

2.0.5

2 months ago

2.0.4

2 months ago

2.0.3

2 months ago

2.0.2

2 months ago

2.0.1

2 months ago