-
下载vditor源码,将constants.ts文件中的CDN修改为可使用的网站:
https://ld246.com/js/lib/vditor(目前官网用的就是这) -
执行npm run start,修复ts报错,能解决的就解决,解决不了的就忽略报错(在报错行前面加
// @ts-ignore),直到能成功运行为止 -
执行npm run build,只需要dist包即可
-
将项目依赖中vditor下的dist包替换为新构建的包,并在使用插件并初始化时配置自建CDN地址,如下图:
不配置自建CDN的话还会继续报如下错误:
-
接下来即可正常使用该插件,渲染效果及基础操作配置如下:
<template>
<div id="vditor"></div>
</template>
<script setup lang="tsx" name="Vditor">
import { onBeforeUnmount, onMounted, ref, watch } from "vue";
import Vditor from "vditor";
import { uploadFileNoCategoryApi } from "@/api/modules/commonApi";
import "vditor/dist/index.css";
const props = withDefaults(defineProps<{ content?: string }>(), {
content: ""
});
const emit = defineEmits<{
(e: "changeContent", value: any): void;
}>();
const supportedFiles = [
{ fileType: ".csv", mimeType: "application/csv" },
{ fileType: ".doc", mimeType: "application/msword" },
{ fileType: ".docx", mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" },
{ fileType: ".html", mimeType: "text/html" },
{ fileType: ".md", mimeType: "text/markdown" },
{ fileType: ".pdf", mimeType: "application/pdf" },
{ fileType: ".ppt", mimeType: "application/vnd.ms-powerpoint" },
{ fileType: ".pptx", mimeType: "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
{ fileType: ".txt", mimeType: "text/plain" },
{ fileType: ".png", mimeType: "image/png" },
{ fileType: ".jpg", mimeType: "image/jpg" },
{ fileType: ".jpeg", mimeType: "image/jpeg" },
{ fileType: ".gif", mimeType: "image/gif" }
];
const uploadAccept = supportedFiles.map(item => item.mimeType).join(",");
const contentEditor = ref<Vditor | null>(null);
const wikiContent = ref("");
watch(
() => props.content,
(newVal: any) => {
wikiContent.value = newVal;
if (contentEditor.value) {
contentEditor.value?.setValue(newVal);
}
}
);
function initVditor() {
contentEditor.value = new Vditor("vditor", {
height: 360,
width: "100%",
mode: "sv", // 分屏预览模式
icon: "material",
cdn: `https://ld246.com/js/lib/vditor`,
preview: { mode: "both", actions: [] },
placeholder: "请输入内容...",
toolbarConfig: { pin: true },
toolbar: [
"emoji",
"headings",
"bold",
"italic",
"strike",
"link",
"list",
"ordered-list",
"check",
"outdent",
"indent",
"quote",
"line",
"code",
"inline-code",
"insert-before",
"insert-after",
"upload",
"record",
{
//自定义上传
hotkey: "",
name: "upload",
tipPosition: "s",
tip: "上传图片",
className: "right"
},
"table",
"fullscreen",
"edit-mode",
"undo",
"redo",
{
name: "more",
toolbar: ["code-theme", "content-theme", "export", "outline", "preview", "devtools", "info", "help"]
}
],
cache: { enable: false },
after: () => {
contentEditor.value!.setValue(wikiContent.value);
},
upload: {
accept: uploadAccept, // 规定上传的图片和文件格式
multiple: false,
// url: "/file/v1/api/minio/uploadNoCategory/default/public-agentos", // 请求的接口
// fieldName: "file",
// max: 10 * 1024 * 1024, //上传图片的大小
// extraData: { satoken: storage.get("token") }, // 为 FormData 添加额外的参数
// validate(files) {
// const isLessthan10M = files[0].size / 1024 / 1024 < 10;
// if (!isLessthan10M) {
// // message.error('上传图片大小不能超过 10MB!')
// }
// },
// files: files => {
// console.log("files", files);
// },
// @ts-ignore
async handler(files: File[]) {
const fileName = files[0]?.name;
const formData = new FormData();
formData.append("file", files[0]);
const { code, data }: any = await uploadFileNoCategoryApi({ bizPath: "lastCheck/", formData });
if (code === 1 && data?.shareUrl) {
// 上传图片回显处理
contentEditor.value?.insertValue(``);
return "上传成功";
}
return "上传失败";
},
success(msg) {
console.log("上传成功", msg);
},
error(msg) {
console.log("上传失败", msg);
}
},
blur(value: any) {
// 失焦时进行保存操作,将值传给父组件并进行接口请求
emit("changeContent", value);
}
});
}
onMounted(() => {
initVditor();
});
onBeforeUnmount(() => {
if (contentEditor.value) {
contentEditor.value.destroy();
}
});
</script>
-
markdown内容的回显
不做任何处理时,markdown内容如下图:使用marked插件解析markdown文本后,回显内容如下: