yarn add md-editor-v3
npm install md-editor-v3 --save
<template>
<MdEditor
class="c-markdown"
v-model="modelValue"
:previewOnly="previewOnly"
:language="language"
:languageUserDefined="languageUserDefined"
@HtmlChanged="handleHtmlChange"
@UploadImg="handleUploadImg"
></MdEditor>
</template>
<script lang="ts">
import { Prop } from 'vue-property-decorator'
import { Vue, Options } from 'vue-class-component'
import MdEditor from 'md-editor-v3'
import { uploadFileApi, createFileName } from '@/api/admin/api-admin-assets'
import { ElMessage } from 'element-plus/lib/components'
@Options({
components: { MdEditor }
})
export default class CMarkDown extends Vue {
modelValue = '# hellow';
language = 'my-lang';
// 定义语言具体内容
languageUserDefined = {
'my-lang': {
toolbarTips: {
bold: '加粗',
underline: '下划线',
italic: '斜体',
strikeThrough: '删除线',
title: '标题',
sub: '下标',
sup: '上标',
quote: '引用',
unorderedList: '无序列表',
orderedList: '有序列表',
codeRow: '行内代码',
code: '块级代码',
link: '链接',
image: '图片',
table: '表格',
revoke: '后退',
next: '前进',
save: '保存',
prettier: '美化',
pageFullscreen: '浏览器全屏',
fullscreen: '屏幕全屏',
preview: '预览',
htmlPreview: 'html代码预览',
catalog: '目录',
github: '源码地址'
},
titleItem: {
h1: '一级标题',
h2: '二级标题',
h3: '三级标题',
h4: '四级标题',
h5: '五级标题',
h6: '六级标题'
},
imgTitleItem: {
link: '添加链接',
upload: '上传图片',
clip2upload: '裁剪上传'
},
linkModalTips: {
title: '添加',
descLable: '链接描述:',
descLablePlaceHolder: '请输入描述...',
urlLable: '链接地址:',
UrlLablePlaceHolder: '请输入链接...',
buttonOK: '确定'
},
clipModalTips: {
title: '裁剪图片上传',
buttonUpload: '上传'
},
copyCode: {
text: '复制代码',
tips: '已复制'
}
}
};
@Prop()
previewOnly?:boolean
// 获取返回的html字符串
handleHtmlChange (html: string): void {
// TODO 防抖
this.$emit('htmlChange', html)
}
// 上传图片
async handleUploadImg (
files: FileList,
callback: (urls: string[]) => void
): Promise<void> {
// 重写上传注意事项,单文件处理
const fd = new FormData()
fd.append('file', files[0])
fd.append('fileName', createFileName('images', files[0].name))
const { code, message, data } = await uploadFileApi(fd)
if (code === 200) {
const urls: string[] = [data.fullPath]
callback(urls)
ElMessage({ type: 'success', message })
} else {
ElMessage({ type: 'error', message })
}
// TODO 多图片
// 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))
}
}
</script>
<style lang="less" scoped></style>
坑点
注意:
使用md排版内容格式的使用
previewOnly
属性,作为展示时,不会有编辑tab
使用html排版内容时v-html
进行内容绑定,
<div class="md-preview github-theme md-scrn" v-html="htmlTxt">
</div>
html内容进行回显的时候,code language-js 样式丢失