vue3中通过vditor插件实现自定义上传图片、录入echarts、脑图、markdown语法的编辑器

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自定义组件

<template><div><div:id="vidtorId"class="vditor":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)、分屏预览(sv)value: 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 t="1696926237451" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2371" width="180" height="180"><path d="M512 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-id="2372"></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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/36236.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

消息队列选型之 Kafka vs RabbitMQ

在面对众多的消息队列时&#xff0c;我们往往会陷入选择的困境&#xff1a;“消息队列那么多&#xff0c;该怎么选啊&#xff1f;Kafka 和 RabbitMQ 比较好用&#xff0c;用哪个更好呢&#xff1f;”想必大家也曾有过类似的疑问。对此本文将在接下来的内容中以 Kafka 和 Rabbit…

阿里AI-Spring Cloud Alibaba AI:快速搭建自己的通义千问

本文基于官方文档。 Spring AI 官方文档&#xff1a;Spring AI :: Spring AI Reference 中文文档&#xff1a;Spring AI 简介 - spring 中文网 (springdoc.cn) Spring AI 是 Spring 官方社区项目&#xff0c;旨在简化 Java AI 应用程序开发&#xff0c;让 Java 开发者像使用…

流光卡片,生成炫酷文字,开源API

https://fireflycard.shushiai.com/ 这是我的一个网站&#xff0c;流光卡片&#xff0c;主要功能是帮你制作酷炫的文字卡片&#xff0c;用精美的卡片让你的文字生动起来。 展示效果如下&#xff1a; 你可以用它制作卡片&#xff0c;来记录自己的表达。支持设定卡片背景、LOGO…

梗图生成器突然爆红;ElevenLabs发布IOS APP 高质量语音朗读手机各种文本内容;开源工作流架构ControlFlow

✨ 1: 梗图生成器 fabianstelzer 在Glif做的一个超强meme生成器 Glif 是一个工作流&#xff0c;能生成文字图片和视频&#xff0c;用工作流的形式可以完成很多的花样来。 最近爆红的梗图生成器&#xff0c;WOJAK MEME GENERATOR &#xff0c;也是用工作流的形式来生成这些有…

宝塔面板之 wwwroot修改不了权限

宝塔使用Apache环境&#xff0c;搭建网站出现 You don’t have permission to access this resource.Server unable to read h出错时的解决办法 今天由于某些原因导致我宝塔 在Apache和Nginx运行环境下不断切换&#xff0c;结果我网站全部不能正常打不开了 结果我发现原本宝塔…

boss直聘招聘数据可视化分析

boss直聘招聘数据可视化分析 一、数据预处理二、数据可视化三、完整代码一、数据预处理 在 上一篇博客中,笔者已经详细介绍了使用selenium爬取南昌市web前端工程师的招聘岗位数据,数据格式如下: 这里主要对薪水列进行处理,为方便处理,将日薪和周薪的数据删除,将带有13薪…

自媒体内容创作者必备:ChatGPT助你提升文章质量

随着自媒体的迅猛发展&#xff0c;越来越多的人加入到内容创作的行列。然而&#xff0c;要在这个竞争激烈的领域脱颖而出&#xff0c;不仅需要创意和独特的观点&#xff0c;更需要高质量的文章内容。在这方面&#xff0c;ChatGPT作为一个智能写作助手&#xff0c;能够帮助自媒体…

靠!AI绘画月入过万!是否现实?

前言 AI人工智能已经出现在了越来越多领域中&#xff0c;比如最近一段时间&#xff0c;AI绘画就受到了许多人的关注&#xff0c;一来&#xff0c;其背后隐藏的版权问题、替代性问题引发了人们的广泛讨论&#xff0c;再者&#xff0c;AI绘画在短期时间内成为了流量密码&#xf…

暑假追高必备:ChildLife全新钙镁锌小绿钙

2024年暑假将至&#xff0c;家长们对于孩子的健康关注再次提升&#xff0c;其中补钙成为许多家长关注的重点。暑假期间&#xff0c;孩子有更多时间进行户外活动&#xff0c;加上高温流汗多&#xff0c;身体的钙更容易流失&#xff0c;因此需要额外地补充。为此&#xff0c;美国…

工业AIoT竞赛流程

不要点到重置&#xff01;&#xff01;&#xff01;要刷新虚拟机就点重启 xshell连接虚拟机&#xff1a;ssh rootPublic IP 环境构建 vim /etc/hosts 按 i 进入插入模式&#xff0c;加内网ip和主机名&#xff0c;按esc&#xff0c;按 : &#xff0c;按wq 三个虚拟机都这样配 …

创新实训博客(十三)——admin前端工作效果

管理/教师端前端工作汇总education-admin&#xff1a; 首先是登录注册页面的展示 管理员 首页 管理员登录后的首页如下图所示 管理员拥有所有的权限 课程管理 1、可以查看、修改、增添、删除课程列表内容 2、可以对课程资源进行操作 3、可以对课程的类别信息进行管理&…

什么类型的网站需要配置OV证书

目录 什么网站更适合OV证书&#xff1a; 申请OV需要注意&#xff1a; 申请单位组织验证型OV SSL证书的详细步骤 OV SSL证书全称Organization Validation SSL(组织验证性SSL证书)&#xff0c;是一种需要验证网站真实身份的数字证书。通过证书颁发机构审查网站企业身份和域名所…

3D模型优化10个最佳实践

对于许多在建模、渲染和动画方面经验丰富的 3D 建模者来说&#xff0c;3D 优化可能是一个令人畏惧的过程 - 特别是当你正在优化实时应用程序的 3D 模型时&#xff01; 在 Google 上快速搜索“如何优化 3D 文件”将会出现一些建议&#xff0c;例如减少多边形数和消除多余的顶点。…

为什么叫云计算?云计算的优势有哪些

说起云计算大家并不会感到陌生&#xff0c;那么为什么叫云计算&#xff1f;云计算技术的引入通常会使企业的信息技术应用更高效、更可靠、更安全。云计算支持用户在任意位置、使用各种终端获取应用服务。使用了数据多副本容错、计算节点同构可互换等措施来保障服务的高可靠性&a…

等保测评中的问题与建议

随着信息技术的广泛使用和飞速发展&#xff0c;网络安全已逐渐演变为威胁经济社会发展的关键议题。信息安全的范围涵盖了政治、商务、军事、教育等多个方面。其中&#xff0c;信息的存储、分享以及管理&#xff0c;主要取决于政府的宏观规划和决策、商业运作的信息、银行的财务…

构建 Audio Unit 应用程序

构建 Audio Unit 应用程序 构建 Audio Unit 应用程序从选择设计模式开始I/O Pass ThroughI/O Without a Render Callback FunctionI/O with a Render Callback FunctionOutput-Only with a Render Callback Function其他设计模式 构建应用程序配置 audio session指定 audio uni…

金融行业自动化运维的研究与实践

金融行业自动化运维的研究与实践 在金融行业中&#xff0c;信息技术&#xff08;IT&#xff09;运维已经成为保障业务连续性和稳定性的重要环节。随着金融业务的复杂化和信息系统的多样化&#xff0c;传统的手工运维模式已无法满足高效、安全的需求。自动化运维技术的应用变得…

流计算状态算子灵活开发指南

随着实时数据流处理需求的不断增长&#xff0c;高效、可扩展的流计算框架变得愈发重要。DolphinDB 作为一款高性能分布式时间序列数据库&#xff0c;不仅在数据存储和查询上表现出色&#xff0c;还通过引入面向对象编程&#xff08;OOP&#xff09;编程范式&#xff0c;使得开发…

聚焦 HW 行动,构筑重保邮件安全防线

随着信息技术的飞速发展&#xff0c;网络安全已成为国家安全的重要组成部分。HW行动作为国家级网络安全演练&#xff0c;通过模拟实战攻防&#xff0c;检验和提升国家关键信息基础设施的防护能力。 CACTER凭借多年HW防护经验&#xff0c;提供全面的邮件安全防护体系&#xff0…

MySQL详细介绍:开源关系数据库管理系统的魅力

学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把手教你开发炫酷的vbs脚本制作(完善中……&#xff09; 4、牛逼哄哄的 IDEA编程利器技巧(编写中……&#xff09; 5、面经吐血整理的 面试技…