開發(fā)背景
這一切都源于在開發(fā)vue3-admin的demo內(nèi)容時,沒有合適的編輯器組件。
在線預(yù)覽
說明
僅支持 vue3 項目下使用,使用 jsx 語法開發(fā),支持在 tsx 項目使用。為了減小插入,沒有使用less.modifyVars方法來切換主題,而采用了替換 class 名稱的方式。
代碼倉庫:md-editor-v3
功能一覽
- 快捷插入內(nèi)容工具欄、編輯器瀏覽器全屏、頁面內(nèi)全屏等;
- 內(nèi)置的白色主題和暗黑主題,支持綁定切換;
- 支持快捷鍵插入內(nèi)容;
- 支持使用 prettier 格式化內(nèi)容(使用 CDN 方式引入,只支持格式化 md 內(nèi)容,可在代碼內(nèi)設(shè)置關(guān)閉);
- 支持多語言,支持自行擴展語言;
- 支持復(fù)制粘貼上傳圖片;
- ...
更多功能待后續(xù)更新,若有想要的功能未開發(fā),請留言~
預(yù)覽圖
默認模式下:
image
暗黑模式下:
image
apis
注意在 jsx 下需使用 modelValue 配合 onChange 方法完成數(shù)據(jù)綁定,在 vue 模板語法下,可以直接使用 v-modal 指令~
props
| 名稱 | 類型 | 默認值 | 說明 |
|---|---|---|---|
| modelValue | String | '' | md 編輯內(nèi)容,vue 模板支持雙向綁定(v-model="value") |
| editorClass | String | '' | 編輯器最外層樣式 |
| hljs | Object | null | 項目中使用到了 highlight,可將實例直接傳遞,生產(chǎn)環(huán)境則不會請求 CDN,需要手動導(dǎo)入支持的高亮代碼樣式 |
| highlightJs | String | highlight.js | highlightJs CDN |
| highlightCss | String | atom-one-dark | 預(yù)覽高亮代碼樣式 |
| historyLength | Number | 10 | 最大記錄操作數(shù)(太大會占用內(nèi)存) |
| pageFullScreen | Boolean | false | 瀏覽器內(nèi)全屏 |
| preview | Boolean | true | 預(yù)覽模式 |
| htmlPreview | Boolean | false | html 預(yù)覽 |
| language | String | 'zh-CN' | 內(nèi)置中英文('zh-CN','en-US'),可自行擴展其他語言,同時可覆蓋內(nèi)置的中英文 |
| languageUserDefined | Array | [{key: StaticTextDefaultValue}] | 通過這里擴展語言,修改 language 值為擴展 key 即可,類型申明可手動導(dǎo)入 |
| toolbars | Array | [all] | 選擇性展示工具欄,可選內(nèi)容如下[toolbars] |
| prettier | Boolean | true | 是否啟用 prettier 優(yōu)化 md 內(nèi)容 |
| prettierCDN | String | standalone | |
| prettierMDCDN | String | parser-markdown | |
| editorName | String | 'editor' | 當(dāng)在同一頁面放置了多個編輯器,最好提供該屬性以區(qū)別某些帶有 ID 的內(nèi)容 |
[toolbars]
[
'bold',
'underline',
'italic',
'strikeThrough',
'title',
'sub',
'sup',
'quote',
'unorderedList',
'orderedList',
'codeRow',
'code',
'link',
'image',
'table',
'revoke',
'next',
'save',
'pageFullscreen',
'fullscreen',
'preview',
'htmlPreview',
'github'
];
自定義語言,需要替換的內(nèi)容如下(某些字段若不主動提供,可能會造成頁面不美觀):
[StaticTextDefaultValue]
export interface StaticTextDefaultValue {
toolbarTips?: ToolbarTips;
titleItem?: {
h1?: string;
h2?: string;
h3?: string;
h4?: string;
h5?: string;
h6?: string;
};
linkModalTips?: {
title?: string;
descLable?: string;
descLablePlaceHolder?: string;
urlLable?: string;
UrlLablePlaceHolder?: string;
buttonOK?: string;
buttonUpload?: string;
};
}
事件綁定
| 名稱 | 入?yún)?/th> | 說明 |
|---|---|---|
| onChange | v:String | 內(nèi)容變化事件(當(dāng)前與textare的oninput事件綁定,每輸入一個單字即會觸發(fā)) |
| onSave | v:String | 保存事件,快捷鍵與保存按鈕均會觸發(fā) |
| onUploadImg | files:FileList, callback:Function | 上傳圖片事件,彈窗會等待上傳結(jié)果,務(wù)必將上傳后的 urls 作為 callback 入?yún)⒒貍?/td> |
快捷鍵
主要以CTRL搭配對應(yīng)功能英文單詞首字母,沖突項添加SHIFT,再沖突替換為ALT。
| 鍵位 | 功能 | 說明 | 開發(fā)標(biāo)記 |
|---|---|---|---|
| CTRL + S | 保存 | 觸發(fā)編輯器的onSave回調(diào) |
√ |
| CTRL + B | 加粗 | **加粗** |
√ |
| CTRL + U | 下劃線 | <u>下劃線</u> |
√ |
| CTRL + I | 斜體 | *斜體* |
√ |
| CTRL + 1-6 | 1-6 級標(biāo)題 | # 標(biāo)題 |
√ |
| CTRL + ↑ | 上角標(biāo) | <sup>上角標(biāo)</sup> |
√ |
| CTRL + ↓ | 下角標(biāo) | <sub>下角標(biāo)</sub> |
√ |
| CTRL + Q | 引用 | > 引用 |
√ |
| CTRL + O | 有序列表 | 1. 有序列表 |
√ |
| CTRL + L | 鏈接 | [鏈接](https://imbf.cc) |
√ |
| CTRL + T | 表格 |
|表格| 放棄開發(fā)(無法實現(xiàn)) |
x |
| CTRL + Z | 撤回 | 觸發(fā)編輯器內(nèi)內(nèi)容撤回,與系統(tǒng)無關(guān) | √ |
| CTRL + SHIFT + S | 刪除線 | ~刪除線~ |
√ |
| CTRL + SHIFT + U | 無序列表 | - 無序列表 |
√ |
| CTRL + SHIFT + C | 塊級代碼 | 多行代碼塊 | √ |
| CTRL + SHIFT + I | 圖片鏈接 | [圖片上傳失敗...(image-bb3132-1626773067693)] |
√ |
| CTRL + SHIFT + Z | 前進一步 | 觸發(fā)編輯器內(nèi)內(nèi)容前進,與系統(tǒng)無關(guān) | √ |
| CTRL + SHIFT + F | 美化內(nèi)容 | √ | |
| CTRL + ALT + C | 行內(nèi)代碼 | 行內(nèi)代碼塊 | √ |
演示
yarn add md-editor-v3
jsx 語法項目
import { defineComponent, reactive } from 'vue';
import Editor from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';
import hljs from 'highlight.js';
import 'highlight.js/styles/atom-one-dark.css';
export default defineComponent({
setup() {
const md = reactive({
text: 'default markdown content'
});
return () => (
<Editor hljs={hljs} modelValue={md.text} onChange={(value) => (md.text = value)} />
);
}
});
vue 模板項目
<template>
<editor v-model="text" pageFullScreen></editor>
</template>
<script>
import { defineComponent } from 'vue';
import Editor from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';
export default defineComponent({
name: 'VueTemplateDemo',
components: { Editor },
data() {
return {
text: '默認值'
};
}
});
</script>
上傳圖片
默認可以選擇多張圖片,支持粘貼板上傳圖片。
注意:粘貼板上傳時,如果是網(wǎng)頁上的 gif 圖,無法正確上傳為 gif 格式!
async onUploadImg(files: FileList, callback: (urls: string[]) => void) {
const res = await Promise.all(
Array.from(files).map((file) => {
return new Promise((rev, rej) => {
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: any) => item.data.url));
}
結(jié)尾
該項目目前只生存了3周,使用中有bug期待你能留言給我,有想要的功能期待了解哦。