色一把做最好的网站,做安卓icon图标包下载网站,赤峰网站设计,亦庄网站建设价格1、下载Vditor插件
npm i vditor 我的vditor版本是3.10.2#xff0c;大家可以自行选择下载最新版本 官网#xff1a;Vditor 一款浏览器端的 Markdown 编辑器#xff0c;支持所见即所得#xff08;富文本#xff09;、即时渲染#xff08;类似 Typora#xff09;和分屏 …
1、下载Vditor插件
npm i vditor 我的vditor版本是3.10.2大家可以自行选择下载最新版本 官网Vditor 一款浏览器端的 Markdown 编辑器支持所见即所得富文本、即时渲染类似 Typora和分屏 - 链滴 示例 Vditor 示例 - 链滴 2、引入vue文件
import Vditor from vditor;
import vditor/dist/index.css; 3、封装vditor自定义组件
templatedivdiv:idvidtorIdclassvditor:class{ vditor-hidden: showPreview }/div/div
/template
script setup
import Vditor from vditor;
import vditor/dist/index.css;
import { getToken } from /utils/auth;
const { proxy } getCurrentInstance();
const props defineProps({height: {type: [Number, String],default: inherit,},modelValue: {type: String,default: ,},knwlgId: {type: String,default: ,},showPreview: {type: Boolean,default: false,},disabled: {type: Boolean,default: false,},// 额外的formData参数extraData: {type: Object,default: () ({}),},uploadURL: {type: String,default: ,},previewURL: {type: String,default: /ekms/images/v1/preview/,},placeholder: {type: String,default: ,},
});const vidtorId ref(vidtor- new Date() ((Math.random() * 1000).toFixed(0) )
);// 图片上传地址判断这里大家可以根据自己需求写死或通过props传入
const imgUploadUrl computed(() {return !props.uploadURL? /ekms/images/v1/upload?knwlgId${props.knwlgId}: props.uploadURL;
});watch(() props.showPreview,(newValue, oldValue) {let previewDom contentEditor.value.vditor.toolbar.elements.preview.firstChild;let isPreview previewDom.className.indexOf(vditor-menu--current) -1;emits(update:showPreview, isPreview ? false : true);previewDom.click();}
);const emits defineEmits([update:modelValue,update:showPreview,setHtml,
]);
const contentEditor ref(null);onMounted(() {contentEditor.value new Vditor(vidtorId.value, {height: props.height,mode: wysiwyg, //所见即所得wysiwyg、即时渲染ir、分屏预览svvalue: props.modelValue,cdn: import.meta.env.VITE_APP_VDITOR_API,placeholder: props.placeholder,toolbarConfig: {pin: true,// hide: true,},// outline: {// enable: true, //展示大纲position默认left// },cache: {enable: false, // 是否使用 localStorage 进行缓存},preview: {mode: both, //显示模式delay: 10,actions: [],theme: {path: ${import.meta.env.VITE_APP_VDITOR_API}/dist/css/content-theme,},},toolbar: [emoji,headings,bold,italic,strike,link,|,list,ordered-list,check,outdent,indent,|,quote,line,code,inline-code,insert-before,insert-after,|,{//自定义上传hotkey: ,name: upload,tip: 上传图片,className: right,},table,|,undo,redo,|,code-theme,content-theme,preview,// 自定义清空内容的菜单{hotkey: ⇧⌘S,name: clearAll,tipPosition: n,tip: 清空内容,className: right,icon: svg t1696926237451 classicon viewBox0 0 1024 1024 version1.1 xmlnshttp://www.w3.org/2000/svg p-id2371 width180 height180path dM512 838.858c10.89 0 19.732-9.158 19.732-20.43v-490.275c0-11.273-8.842-20.43-19.732-20.43s-19.755 9.157-19.755 20.43v490.275c0 11.272 8.842 20.43 19.755 20.43M629.877 838.813c10.935 0.428 20.138-8.37 20.475-19.688l28.665-489.69c0.427-11.272-8.077-20.745-18.99-21.195-10.935-0.405-20.137 8.415-20.475 19.688l-28.665 489.713c-0.405 11.317 8.1 20.767 18.99 21.172M848.038 185.142h-197.708v-81.653c0-22.545-17.685-40.882-39.51-40.882h-197.64c-21.87 0-39.532 18.338-39.532 40.882v81.653h-197.685c-10.913 0-19.755 9.158-19.755 20.475 0 11.272 8.843 20.407 19.755 20.407h39.577l39.488 653.67c6.367 44.73 35.415 81.72 79.065 81.72h355.793c43.65 0 71.573-37.44 79.088-81.72l39.488-653.67h39.578c10.867 0 19.755-9.135 19.755-20.408 0-11.317-8.888-20.475-19.755-20.475M413.157 103.49h197.64v81.653h-197.64v-81.653zM729.418 879.695c-2.655 21.555-17.73 40.86-39.533 40.86h-355.793c-21.87 0-36.54-19.057-39.532-40.86l-39.532-653.67h513.945l-39.555 653.67zM394.145 838.858c10.89-0.473 19.373-9.9 18.99-21.195l-29.070-489.712c-0.427-11.273-9.585-20.070-20.475-19.665-10.913 0.428-19.463 9.9-19.013 21.173l29.093 489.712c0.36 11.295 9.54 20.070 20.475 19.688z p-id2372/path/svg,click() {contentEditor.value.setValue();},},],// vditor结构渲染完成后after: () {emits(setHtml, getValue(), getHTML());// 这里根据传入的disabled来设置vditor是否可输入内容props.disabled contentEditor.value.disabled();},input: () {// 变更事件回调emits(setHtml, getValue(), getHTML());},// 上传图片upload: {accept: image/*, // 图片类型fieldName: file,url: import.meta.env.VITE_APP_BASE_API imgUploadUrl.value, // 图片上传的接口路径extraData: props.extraData, // 要携带的额外的formData参数headers: {Authorization: Bearer getToken(), // 用户身份信息},filename(name) { // 过滤特殊字符return name.replace(/[^(a-zA-Z0-9\u4e00-\u9fa5\.)]/g, ).replace(/[\?\\/:|\*\[\]\(\)\$%\{\}~]/g, ).replace(/\\s/g, );},// 粘贴图片的情况下上传的接口路径linkToImgUrl: import.meta.env.VITE_APP_BASE_API imgUploadUrl.value,max: 20 * 1024 * 1024,multiple: false,withCredentials: false,// 图片上传校验可以校验图片大小及类型validate(files) {const isLt2M files[0].size / 1024 / 1024 20;if (!isLt2M) {proxy.$modal.msgError(上传图片大小不能超过 20MB!);}if (!files[0].type.includes(image)) {return proxy.$modal.msgError(仅支持上传图片);}},//粘贴图片回显处理如果有图片加了防盗链则让后台代理替换成自己的图片linkToImgFormat(responseText) {let res JSON.parse(responseText);if (!res.data?.imgId) return;let end JSON.stringify({msg: ,code: 0,data: {originalURL:import.meta.env.VITE_APP_BASE_API props.previewURL res.data?.imgId, //图片原始地址记录到本地文件中可以防止跨站点调用。url:import.meta.env.VITE_APP_BASE_API props.previewURL res.data?.imgId, //图片链接记录到本地文件中可以防止跨站点调用。},});return end;},format(files, responseText) {var res JSON.parse(responseText);if (!res.data?.imgId) return;//图片回显nextTick(() {emits(setHtml, getValue(), getHTML());});return JSON.stringify({msg: ,code: 0,data: {errFiles: [],succMap: {[res.data.imgPath]:import.meta.env.VITE_APP_BASE_API props.previewURL res.data?.imgId,},},});},},});
});function getValue() {return contentEditor.value.getValue(); //获取 Markdown 内容
}// 获取html结构
function getHTML() {let dom document.querySelector(.vditor-content .vditor-wysiwyg .vditor-reset)?.innerHTML;return dom;
}function setValue(value) {return contentEditor.value.setValue(value); //设置 Markdown 内容
}defineExpose({getHTML,setValue,
});
/script