附cherry-markDown官网及api使用示例
考虑到复用性,我在插件的基础上做了二次封装,步骤如下:
1.下载 npm install cherry-markdown --save
2..先在html中定义一个markDown容器,设置id及样式
<template>
<div v-loading="loading" element-loading-text="文件上传中...">
<div @click.prevent.stop>
<div :id="mdId" :style="{ height: height + 'px' }"></div>
</div>
</div>
</template>
3.在js中引入markDown
import Cherry from "cherry-markdown";
import "cherry-markdown/dist/cherry-markdown.min.css";
4.定义需要使用的变量并初始化markDown
(一部分是从父组件传过来的,loading是在上传图片/视频/附件的时候使用)
const props = defineProps({
height: {
type: Number,
default: 600,
},
modelValue: {
type: String,
default: "",
},
knwlgId: {
type: String,
default: "",
},
mdId: {
type: String,
default: "markdown-container",
},
});
const emits = defineEmits(["update:modelValue", "setHtml"]);
const cherrInstance = ref(null);
const loading = ref(false);
onMounted(() => {
//初始化markDown
initCherryMD();
});
5.初始化markDown
toolbars.toolbar内的togglePreview就是预览按钮
设置默认模式:editor.defaultModel
// defaultModel 编辑器初始化后的默认模式,一共有三种模式:1、双栏编辑预览模式;2、纯编辑模式;3、预览模式
// edit&preview: 双栏编辑预览模式
// editOnly: 纯编辑模式(没有预览,可通过toolbar切换成双栏或预览模式)
// previewOnly: 预览模式(没有编辑框,toolbar只显示“返回编辑”按钮,可通过toolbar切换成编辑模式)
// defaultModel: 'edit&preview',
const initCherryMD = (value, config) => {
cherrInstance.value = new Cherry({
id: props.mdId,
value: props.modelValue,
fileUpload: fileUpload,
emoji: {
useUnicode: true,
},
header: {
anchorStyle: "autonumber",
},
editor: {
defaultModel: "editOnly",
},
toolbars: {
theme: "light",
toolbar: [
"bold",
"italic",
"underline",
"strikethrough",
"|",
"color",
"header",
"|",
"list",
"image",
{
insert: [
"audio",
"video",
"link",
"hr",
"br",
"code",
"formula",
"toc",
"table",
"line-table",
"bar-table",
"pdf",
"word",
],
},
"graph",
"settings",
// "switchModel",
"togglePreview",
],
bubble: [
"bold",
"italic",
"underline",
"strikethrough",
"sub",
"sup",
"|",
"size",
"color",
],
float: [
"h1",
"h2",
"h3",
"|",
"checklist",
"quote",
"quickTable",
"code",
],
customMenu: [],
},
callback: {
afterChange: afterChange,
beforeImageMounted: beforeImageMounted,
},
});
};
6.定义上传图片、获取数据的方法(这里可以实际需求做判断)
// 上传通用接口未实现audioVideo
const fileUpload = (file, callback) => {
if (file.size / 1024 / 1024 > 200) {
return proxy.$modal.msgError("请上传200M以内的图片!");
}
if (!file.type.includes("image")) {
return proxy.$modal.msgError("仅支持上传图片!");
}
const formData = new FormData();
formData.append("file", file);
console.log(file, "file");
loading.value = true;
uploadImg(props.knwlgId, formData)
.then((res) => {
loading.value = false;
callback(
import.meta.env.VITE_APP_BASE_API +
"/ekms/images/v1/preview/" +
res.data.imgId
);
})
.catch(() => {
loading.value = false;
});
};
// 变更事件回调
const afterChange = (e) => {
emits("setHtml", getCherryContent(), getCherryHtml());
};
// 获取渲染后html内容
const getCherryHtml = () => {
const result = cherrInstance.value.getHtml();
// console.log(result, "get");
return result;
};
// 获取markdown内容
const getCherryContent = () => {
const result = cherrInstance.value.getMarkdown();
return result;
};
// 设置markdown内容
const setCherryContent = (val) => {
cherrInstance.value.setMarkdown(val, 1);
};
// 图片加载回调
const beforeImageMounted = (e, src) => {
return { [e]: src };
};
defineExpose({
getCherryHtml,
setCherryContent,
});
使用该组件:
<CherryMD
ref="MDRef"
v-model="mdContent"
:knwlgId="artDetails.pkId"
@setHtml="getContent"
/>
const mdContent = ref("");
//设置默认值
mdContent.value = res.data.content;
nextTick(() => {
proxy.$refs.MDRef.setCherryContent(res.data.content || "");
});
// 获取文章结构信息
const getContent = (content, html) => {
mdHtml.value = html;
mdContent.value = content;
changeArticle();
};