在vite5和vue3开发环境中使用jodit4富文本编辑器,并添加自定义插件和使用highlight.js实现代码块高亮(附其他自定义配置项和全部代码)

最近富文本编辑器jodit终于更新发布到了4.0版本,加入了css变量、有更好的typescript支持,截止发文时的版本是:4.0.5,看到有了新版本于是便想着将本地项目中的jodit版本也进行升级,琢磨着再丰富和添加一些功能,就开始了各种踩坑,在这里做个分享。
jodit Pro版集成的功能更多,但需要付费才能使用。
相对于jodit3.x版本,引入方式有了变化,配置项差别不大,对于jodit3.x版本的使用和配置,可以参考我之前发布过的文章 vue3使用jodit富文本编辑器,自定义各项配置及组件封装。对于jodit4.0版本和highlight.js的详细升级内容和使用配置等可参阅官方文档:

  • jodit官网地址:https://xdsoft.net/jodit;
  • highlight.js官网地址:https://highlightjs.readthedocs.io/en/latest/readme.html

本文篇幅较长,主要有以下几点:

  1. 坑点说明;
  2. 添加自定义插件;
  3. 使用highlight.js高亮代码块(jodit里面的代码块只是将选中的内容包裹在pre标签中,并没有样式和代码高亮);
  4. 其他配置。

开发环境基于vite5.0.xvue3.4.x,项目主要依赖和版本如下:

{"dependencies": {"@highlightjs/vue-plugin": "^2.1.0","element-plus": "^2.5.1","highlight.js": "^11.9.0","jodit": "^4.0.5","vue": "^3.4.14","vue-router": "^4.2.5"},"devDependencies": {"@vitejs/plugin-vue": "^5.0.3","sass": "^1.69.6","vite": "^5.0.11","vite-plugin-compression2": "^0.11.0"}
}

jodit4.0版本提供了5种方式可选择使用,分别是:es5、es2015、es2018、es2021、esm(es2021的基础功能版)。一开始我选择使用的是esm的基础版,再按需引入的方式,但这也成为了主要坑点,接下来会讲到,首先安装后引入:

npm i jodit  //或者
yarn add jodit

创建组件JoditEditor,新建index.vue,代码如下:

<template><textarea id="editorRef" ref="editorRef" name="editor"></textarea>
</template><script setup>
import { watch, onMounted, onBeforeUnmount } from "vue";
import "jodit/es2021/jodit.min.css";
import { Jodit } from "jodit/esm/index.js";defineOptions({name: "JoditEditor",
});
const props = defineProps({config: { type: Object, default: () => ({}) },
});
//与父组件传入的值动态绑定
let modelValue = defineModel();//vue3.4.x版本正式支持
//创建Jodit实例
let editorInstance = null;
//配置项
let defaultConfig = {theme: "default", //主题:默认default,暗色darkplaceholder: "请输入内容...",textIcons: false,//工具栏是否显示文字,不用icon图标展示zIndex: 10,language: "zh_cn",//使用中文width: "100%",height: "100%",minHeight: 400,//需要在工具栏上使用到的功能插件buttons: ["source",//源代码"bold",//加粗"italic",//斜体"underline",//下划线"strikethrough",//删除线"eraser", //橡皮擦"|", //分割符"superscript",//上标"subscript",//下标"ul","ol","indent",//增加缩进"outdent",//减少缩进"align", //对齐方式"|","font",//字体"fontsize",//字体大小"paragraph",//格式块,包含标题1~4,引用,代码"brush",//颜色"lineHeight",//行高"|","image",//图片上传"file",//文件上传"copyformat",//复制格式"selectall", //全选"hr",//分割线"table",//表格"link",//超链接"symbols",//特殊符号"undo",//撤销"redo",//恢复"fullsize",//全屏"preview",//预览],
};onMounted(() => {//合并组件传入的配置项并创建实例editorInstance = Jodit.make("#editorRef", {...defaultConfig,...props.config,});//监听编辑器内容变化editorInstance.events.on("change", (newValue) => {modelValue.value = newValue;});console.log(editorInstance);
});onBeforeUnmount(() => {//组件销毁editorInstance.destruct(); editorInstance = null;
});
watch(modelValue, (newValue) => {if (editorInstance.value !== newValue) {editorInstance.value = newValue;}
});
</script><style lang="scss">
.jodit-checkbox,
.jodit-ui-checkbox__input {appearance: checkbox;-webkit-appearance: checkbox;
}
.jodit .jodit-input {color: #666;
}
.jodit-ui-button_variant_primary {background-color: var(--el-color-primary);
}
.jodit-ui-button_variant_primary:hover:not([disabled]) {background-color: var(--el-color-primary-light-3);
}
</style>

组件的使用示例:

<template><div class="Jodit_box"><JoditEditor v-model="content" :config="config" /><el-button type="primary" @click="handleGet" size="large" class="get_btn">获取编辑器内容</el-button></div>
</template><script setup>
import { ref } from "vue";
import JoditEditor from "../components/joditEditor/index.vue";let content = ref("加载初始内容...");
//配置项
let config = {theme: "default", //darkheight: 500,
};
//模拟异步加载初始内容
setTimeout(() => {content.value = `<pre><code class="hljs">let a=123;\n</code></pre>`;
}, 2000);
//获取编辑器内容
function handleGet() {console.log(content.value);
}
</script><style  scoped>
.get_btn {margin-top: 20px;
}
</style>

页面上呈现是这样的:
在这里插入图片描述
工具栏上直接显示文字,而不是图标,显示文字的功能插件就需要单独引入,可以通过路径查找:node_modules/jodit/esm/plugins,插件都在文件夹plugins里面,与在buttons里配置的名字基本一致,引入显示文字的插件:

import "jodit/esm/plugins/add-new-line/add-new-line.js";
import "jodit/esm/plugins/copy-format/copy-format.js";
import "jodit/esm/plugins/fullsize/fullsize.js";
import "jodit/esm/plugins/hr/hr.js";
import "jodit/esm/plugins/line-height/line-height.js";
import "jodit/esm/plugins/preview/preview.js";
import "jodit/esm/plugins/source/source.js";
import "jodit/esm/plugins/symbols/symbols.js";

但是还剩三项eraser(橡皮擦)、align(对齐方式)、selectall(全选),找完了也没有,就用不了。
另外插入页面的表格也只可以在表格中输入,并不能对表格进行编辑,考虑是否因为没有引入完整表格插件的缘故,便试着引入:

import 'jodit/esm/plugins/table/table.js';

这时出现了最大的坑点,出现报错并且页面不能正常显示

在这里插入图片描述
既然不能用,那我删除这行表格引用代码该可以了吧,但是刷新页面后还是这个错误,于是我重启了终端,还是这个错误,清除浏览器缓存甚至重启了浏览器问题依旧,明明引用代码已删除,就很奇怪,第一次遇到这种情况,还有引用select等一些插件也会出现这个错误:

//这个引入也会报错
import 'jodit/esm/plugins/select/select.js';

在这儿折腾了许久,终于找到了 两种解决方法,前提都需要先删除导致出错的插件引入代码:

  1. 换一个jodit版本,比如切换到上一个版本jodit 4.0.4,但如果在这个版本中继续引入会出错的插件代码,问题一样会出现,又只能切换到另一个版本;
  2. 删除node_modules文件夹下的.vite文件夹,然后重启终端。

plugins文件夹下大概有60个左右插件,并未全部测试还有哪些也会报错的,大家可自行测试,按如上方法解决即可。
最后放弃使用esm方式,还是选择使用es2021的全部引入方式,将代码稍做修改:

- // import { Jodit } from "jodit/esm/index.js";
+  import * as JoditEditor from "jodit/es2021/jodit.min.js";
+  let Jodit = JoditEditor?.Jodit;

页面显示效果正常,插入的表格也能编辑
在这里插入图片描述
接下来是自定义代码高亮插件,先安装highlight.js并引入:

npm i highlight.js
//或者
yarn add highlight.js
 import hljs from "highlight.js";import "highlight.js/styles/default.min.css";//引入自己喜欢的主题样式(styles文件夹下有多种主题,可自行选择)// import "highlight.js/styles/atom-one-dark.min.css";import "highlight.js/styles/panda-syntax-dark.min.css";

自定义插件的方式可以通过配置项的extraButtons或者controls,还可以使用Jodit.plugins.add()方法去实现,这里我用的是配置项controls的方式,关键部分都加了注释,代码如下:

import codePng from "../../assets/code.png";
let defaultConfig = {i18n: {zh_cn: {Title: "标题",Link: "链接","Change mode": "html模式",codeBlock: "代码块",//插件的中文名},},//需要在工具栏上使用到的功能插件buttons: [//......,"codeBlock"//添加插件codeBlock
],//创建属性配置(对添加在编辑器内的标签元素添加属性配置,如class、style等)createAttributes: {// 为code标签添加class为 hljscode: {class: "hljs",},},controls: {paragraph: {list: Jodit.atom({h1: "Heading 1",h2: "Heading 2",h3: "Heading 3",h4: "Heading 4",blockquote: "Quote",// pre: 'Source code'//注掉编辑器自带的code代码插入}),},//自定义插件codeBlock: {name: "codeBlock",tooltip: "代 码",//显示在工具栏中插件的图标,也可以是网址,我这里用的是本地的图片iconURL: codePng,//选择使用对应的语言高亮,可自行探索实现//list: ["html", "javascript", "css"],//具体实现方法exec(editor) {//editor.s.html是当前选中的内容,且值是只读的console.log("html", editor.s.html);//创建pre、code元素,highlight.js需要将高亮的代码块放在pre标签里的code标签中let pre = document.createElement("pre");let code = document.createElement("code");//为code元素添加classcode.classList = "hljs";//将字符串中的<br>、</p>加上换行符,不然高亮后的代码不换行并且会显示转义字符,如&gt;等code.innerHTML = editor.s.html.replace(/\<br\>/g, "\n").replace(/\<\/p\>/g, "</p>\n");pre.appendChild(code);//使用hljs对code进行高亮,自动识别,注意highlightElement接收的参数是dom元素,不是字符串hljs.highlightElement(code);//将处理完成后的pre元素插入到编辑器中editor.s.insertHTML(pre);},},},
};
onMounted(() => {//合并组件传入的配置项并创建实例editorInstance = Jodit.make("#editorRef", {...defaultConfig,...props.config,});//监听编辑器内容变化editorInstance.events.on("change", (newValue) => {if (newValue.includes("language-undefined")) {//hljs不能识别或者插入一个空的代码标签时,会加上language-undefined的class,//这里将undefined替换为默认的plaintext文本显示newValue = newValue.replace(/language-undefined/g, "language-plaintext");}modelValue.value = newValue;});
});

有一种情况需要说明一下,直接先在工具栏上先点击插入代码块时,会在编辑器中生成一个空的code标签,此时里面没有任何内容,可以自行输入代码,然后再次点击工具栏的代码块,才能高亮,在输入时高亮并不是实时的
高亮效果:
在这里插入图片描述

提一下配置项 createAttributes,这是创建属性配置,可以对添加在编辑器内的标签元素添加属性配置,如class、style、dataset等,也就是说当通过插件向编辑器内添加内容时会生成对应的标签元素,比如div、p、blockquote、span等,都会带上配置的属性,示例代码如下:

//配置项中添加createAttributes
let defaultConfig = {//创建标签属性配置(对添加在编辑器内的标签元素添加属性配置,如class、style等)createAttributes: {// 为code标签添加class为 hljscode: {class: "hljs",},//P标签示例,所有的p标签都会添加class="p-box"属性,并添加data-id属性,并设置颜色为红色p: {class: "p-box","data-id": Date.now(),style: {color: "pink",},},},
}

在这里插入图片描述
附上完整代码,其中配置还包括字体、字号、图片上传、中文显示(i18n)等。

<template><textarea id="editorRef" ref="editorRef" name="editor"></textarea>
</template><script setup>
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
import "jodit/es2021/jodit.min.css";
import * as JoditEditor from "jodit/es2021/jodit.min.js";
import hljs from "highlight.js";
import "highlight.js/styles/default.min.css";
// import "highlight.js/styles/atom-one-dark.min.css";
import "highlight.js/styles/panda-syntax-dark.min.css";
import codePng from "../../assets/code.png";defineOptions({name: "JoditEditor",
});
const props = defineProps({config: { type: Object, default: () => ({}) },
});let modelValue = defineModel();let Jodit = JoditEditor?.Jodit;
//创建Jodit实例
let editorInstance;
//配置项
let defaultConfig = {theme: "default", //主题:默认default,暗色darkplaceholder: "请输入内容...",textIcons: false,//工具栏是否显示文字,不用icon图标展示zIndex: 10,language: "zh_cn",width: "100%",height: "100%",minHeight: 400,saveModeInCookie: false,toolbarSticky: false, //工具栏设置stickystatusbar: false, //底部状态栏(左:html元素;右:单词数,字符数统计)image: {//图片相关配置editSrc: false,editStyle: false,useImageEditor: true,},link: {noFollowCheckbox: false,modeClassName: "",},i18n: {zh_cn: {top: "上",right: "右",bottom: "下",left: "左",Title: "标题",Link: "链接","Line height": "行高",Alternative: "描述","Alternative text": "描述","Lower Alpha": "小写英文字母","Lower Greek": "小写希腊字母","Lower Roman": "小写罗马数字","Upper Alpha": "大写英文字母","Upper Roman": "大写罗马数字","Change mode": "html模式",codeBlock: "代 码",},},//需要在工具栏上使用到的功能插件buttons: ["source", //源代码"bold", //加粗"italic", //斜体"underline", //下划线"strikethrough", //删除线"eraser", //橡皮擦"|", //分割符"superscript", //上标"subscript", //下标"ul","ol","indent", //增加缩进"outdent", //减少缩进"align", //对齐方式"|","font", //字体"fontsize", //字体大小"paragraph", //格式块,包含标题1~4,引用,代码"brush", //颜色"lineHeight", //行高"|","image", //图片上传"file", //文件上传"copyformat", //复制格式"selectall", //全选"hr", //分割线"table", //表格"link", //超链接"symbols", //特殊符号"undo", //撤销"redo", //恢复"fullsize", //全屏"preview", //预览"codeBlock",],//创建属性配置(对添加在编辑器内的标签元素添加属性配置,如class、style等)createAttributes: {// 为blockquote标签添加class为 blockquote-boxblockquote: {class: "blockquote-box",},// 为code标签添加class为 hljscode: {class: "hljs",},//比如P标签示例// p: {//   class: "p-box",//   "data-id": Date.now(),//   style: {//     color: "red",//   },// },},controls: {font: {list: Jodit.atom({"Microsoft YaHei": "微软雅黑",KaiTi: "楷体",方正喵呜体: "方正喵呜体","思源宋体 Heavy": "思源宋体",SimHei: "黑体",NSimSun: "新宋体",华文行楷: "华文行楷",}),},fontsize: {list: Jodit.atom([8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 30, 32, 34, 36, 48,]),},paragraph: {list: Jodit.atom({h1: "Heading 1",h2: "Heading 2",h3: "Heading 3",h4: "Heading 4",blockquote: "Quote",// pre: 'Source code' 注掉编辑器自带的code代码插入}),},//自定义插件codeBlock: {name: "codeBlock",tooltip: "代 码",//显示在工具栏中插件的图标,也可以是网址,我这里用的是本地的图片iconURL: codePng,//选择使用对应的语言高亮,可自行探索实现//list: ["html", "javascript", "css"],//具体实现方法exec(editor) {//editor.s.html是当前选中的内容,且值是只读的console.log("html", editor.s.html);//创建pre、code元素,highlight.js需要将高亮的代码块放在pre标签里的code标签中let pre = document.createElement("pre");let code = document.createElement("code");//为code元素添加classcode.classList = "hljs";//将字符串中的<br>、</p>加上换行符,不然高亮后的代码不换行并且会显示转义字符,如&gt;等code.innerHTML = editor.s.html.replace(/\<br\>/g, "\n").replace(/\<\/p\>/g, "</p>\n");pre.appendChild(code);//使用hljs对code进行高亮,自动识别,注意highlightElement接收的参数是dom元素,不是字符串hljs.highlightElement(code);//将处理完成后的pre元素插入到编辑器中editor.s.insertHTML(pre);},},},//上传配置uploader: {url: "/api/uploadImg2", //上传地址processFileName: (key, file, name) => {//key是指formData数据里的key值,默认为files[0],后端获取时需要保持key值一致console.log(1, key);console.log(2, file);console.log(3, name);return ["image", file, name];},isSuccess(res) {return res;},defaultHandlerSuccess(data) {//此处参数的值默认是接口返回的data值console.log("defaultHandlerSuccess", data);this.s.insertImage(data.url);// data.forEach((item) => {//   this.s.insertImage(item.url); //将图片插入编辑器中,不可省略// });},defaultHandlerError(err) {console.log("defaultHandlerError", err);this.jodit.events.fire("errorMessage", err);},error(err) {console.log("error", err);this.jodit.events.fire("errorMessage", "文件上传失败");},},
};onMounted(() => {//合并组件传入的配置项并创建实例editorInstance = Jodit.make("#editorRef", {...defaultConfig,...props.config,});editorInstance.value = modelValue.value;editorInstance.events.on("change", (newValue) => {if (newValue.includes("language-undefined")) {//hljs不能识别或者插入一个空的代码标签时,会加上language-undefined的class,// 这里将undefined替换为默认的plaintext文本显示newValue = newValue.replace(/language-undefined/g, "language-plaintext");}modelValue.value = newValue;});console.log(editorInstance);
});onBeforeUnmount(() => {editorInstance.destruct(); //组件销毁editorInstance = null;
});watch(modelValue, (newValue) => {if (editorInstance.value !== newValue) {editorInstance.value = newValue;}
});
</script><style lang="scss">
.jodit-checkbox,
.jodit-ui-checkbox__input {appearance: checkbox;-webkit-appearance: checkbox;
}
.jodit .jodit-input {color: #666;
}
.jodit-ui-button_variant_primary {background-color: var(--el-color-primary);
}
.jodit-ui-button_variant_primary:hover:not([disabled]) {background-color: var(--el-color-primary-light-3);
}
//生成引用标签时的样式
.jodit-wysiwyg {.blockquote-box {display: block;padding: 16px;margin: 0 0 24px;border-left: 8px solid var(--el-color-primary-light-5); //#dddfe4;background: #eef0f4 !important;color: rgba(0, 0, 0, 0.5);overflow: auto;word-break: break-word !important;}
}
</style>

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

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

相关文章

掌握Python 99 个实用实例,其中精选算法高频题目以及答案,助力求职Python工程师面试不慌拿offer

掌握Python 99 个实用实例&#xff0c;其中精选算法高频题目以及答案&#xff0c;助力求职Python工程师面试不慌拿offer。 Python由荷兰国家数学与计算机科学研究中心的吉多范罗苏姆于1990年代初设计&#xff0c;作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构&…

给机器人开发个功能让它帮我照看宝宝

本文首发于古月居 这篇博客主要讲述了如何通过OriginBot来看护宝宝&#xff0c;当宝宝的脸不在摄像头的范围之内时&#xff0c;发送消息到钉钉群组&#xff0c;通知家人及时查看。 前言 我在上个月有了宝宝&#xff0c;为了方便照看宝宝&#xff0c;就买了一个带有宝宝看护功能…

OpenLayers实战,OpenLayers点聚合有相同经纬度坐标时无法展开问题解决办法,当缩放级别达到一定等级后强行展开聚合为单个点

专栏目录: OpenLayers实战进阶专栏目录 前言 本章用于解决OpenLayers使用Cluster点聚合情况下,要素(Feature)出现有相同经纬度坐标时无法展开成单独图标的问题解决办法以及当缩放级别达到一定等级后强行展开聚合为单个点的功能。 本章展开后由于经纬度坐标还是同一个点,…

SAP 销售订单审批状态(查询/修改)

销售订单审批状态启用后&#xff0c;前端显示界面如下图 销售订单审批状态读取&#xff1a;STATUS_READ 销售订单审批状态修改&#xff1a;I_CHANGE_STATUS 销售订单审批状态读取 代码样例如下&#xff1a; DATA: lv_objnr TYPE vbak-objnr,lv_objnr_t TYPE jsto-objnr,l…

难道说 IT行业的下一个风口是鸿蒙开发吗?

按往年的习俗&#xff0c;在年底之季有很多HC都会缩减&#xff0c;尤其当下各种裁员的情况下&#xff0c;不管你是在哪个传统开发行业&#xff0c; 如&#xff1a;C/C、Java、前端、后端……等多少都会一股互联网寒流的影响。而今年却出现了一个怪现象&#xff0c;有个岗位在这…

【欢迎您的到来】这里是开源库get_local_info作者的付费专栏

您好&#xff0c; 我是带剑书生&#xff0c;开源库get_local_info的作者&#xff0c;欢迎您的到来&#xff0c;这里是我的付费专栏&#xff0c;会用更简洁的语言&#xff0c;更通俗的话语&#xff0c;来帮助您更好的学习rust&#xff0c;这里不仅仅讲解Rust在某些应用功能实现上…

Java可视化物联网智慧工地综合云平台源码 私有化部署

智慧工地平台围绕建筑施工人、物、事的安全管理为核心&#xff0c;对应研发了劳务实名制、视频监控、扬尘监测、起重机械安全监测、安全帽监测等功能一体化管理的解决方案。 智慧工地是聚焦工程施工现场&#xff0c;紧紧围绕人、机、料、法、环等关键要素&#xff0c;综合运用…

智慧矿山知识点总结

目录 1.第一章数字矿山的定义、基本特征和功能数字矿山的框架结合专业&#xff0c;如何发挥专业优势参与数字矿山建设&#xff08;GPT&#xff09; 2.第二章矿区地质构造和生态环境信息都包括哪些内容地球探测信息技术分类矿山品味与储量矿量估算 3.第三章矿山空间信息获取的仪…

RT-Thread Studio学习(十四)ADC

RT-Thread Studio学习&#xff08;十四&#xff09;ADC 一、简介二、新建RT-Thread项目并使用外部时钟三、启用ADC四、测试 一、简介 本文将基于STM32F407VET芯片介绍如何在RT-Thread Studio开发环境下使用ADC设备。硬件及开发环境如下&#xff1a; OS WIN10STM32F407VET6STM…

基于Springboot的摄影分享网站系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的摄影分享网站系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

Python文件自动化处理

os模块 Python标准库和操作系统有关的操作创建、移动、复制文件和文件夹文件路径和名称处理 路径的操作 获取当前Python程序运行路径不同操作系统之间路径的表示方式 windows中采用反斜杠(\)作为文件夹之间的分隔符 Mac和Linux中采用斜杠(/)作为文件夹之间的分隔符 把文件…

详解React与Vue的性能对比

React 和 Vue 是当前最流行的前端开发框架之一。它们都具有高度的灵活性和可扩展性&#xff0c;但在某些方面有所不同。在本篇文章中&#xff0c;我将详细介绍 React 和 Vue 这两个技术&#xff0c;并比较它们的优点和缺点。 目录 1. React&#xff1a; 1.1 优点&#xff1a; …

2023年第十四届蓝桥杯软件赛省赛总评

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周。 在QQ群上交流答疑&am…

[AI争霸] 普通人看ChatGPT和文心一言那个更好

文章目录 引言便利性准确性总结 引言 从2022/2/24号openAI正式发布chatgpt第一个版本以来&#xff0c;到2023年中旬openAI宣布chatgpt成为用户增长量最快的软件&#xff0c;随后掀起的大模型热。随后国内的各大厂商纷纷推出自己的大模型&#xff0c;首当其冲的就是百度的文心一…

Redis 消息队列和发布订阅

文章目录 基本模式生产者消费者原理&模型redis实现java实现 发布者订阅者原理&模型redis实现java实现 stream模式原理&模型工作原理redis实现Java实现 选型外传 基本模式 采用redis 三种方案&#xff1a; ● 生产者消费者&#xff1a;一个消息只能有一个消费者 ●…

Smart Tomcat

Smart Tomcat插件可以让idea图形化界面让代码部署到tomcat上达成一键打包部署的过程 下面是idea安装使用Smart Tomcat的过程 我们直接在plugins(插件)里搜索Tomcat 然后下载第一个 然后点击Apply(应用) 在一个项目中 第一次使用时要进行配置Smart Tomcat Name 可以不配置…

vscode安装和基本设置

目录 vscode安装和基本设置1.HTML标签2.标签属性3.HTML基本结构4.安装vscode5.安装Live Server插件6.HTML注释7.文档说明8.HTML字符编码9.HTML设置语言10.HTML标准结构 vscode安装和基本设置 1.HTML标签 标签 又称 元素&#xff0c;是HTML的基本组成单位。标签分为&#xff1…

JSP简单学习

jsp是在html中嵌入java代码 jsp也是在j2ee服务端中的java组件 第一次运行 在第一次运行jsp代码时会经历以下步骤&#xff0c;将jsp转为java代码&#xff0c;将java代码转为class文件。 所以通常会比较慢&#xff0c;编译后就好多了。 四大作用域 requestsessionpageapplica…

使用pdfbox 为 PDF 增加水印

使用pdfbox 为 PDF增加水印https://www.jylt.cc/#/detail?activityIndex2&idbd410851b0a72dad3105f9d50787f914 引入依赖 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>3.0.1</ve…

【栈】【字符串和int类型转化】Leetcode 150 逆波兰表达式求值

【栈】【字符串和int类型转化】Leetcode 150 逆波兰表达式求值 解法1 栈 ---------------&#x1f388;&#x1f388;题目链接 Leetcode 150 逆波兰表达式求值 &#x1f388;&#x1f388;------------------- 解法1 栈 字符串转化为int类型数据: Integer.parseInt(s) Long.p…