vue中使用editor.md问题记录
1、背景
在做毕业设计,做的是一个博客的个人网站,用到的技术有springboot 、vue,项目中博客的编写用的是editor.md这个富文本,是开源的项目,这是项目地址,可以点进去下载使用,
2、问题记录
1、开始使用 editor.md
1、下载插件放在vue项目的static目录下
2、index.html(注意引用css 和js文件的路径)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>mu's blog</title>
<link rel="icon" href="static/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="static/editor.md-master/css/editormd.min.css">
<script src="./static/editor.md-master/examples/js/jquery.min.js"></script>
<script src="static/editor.md-master/lib/marked.min.js"></script>
<script src="static/editor.md-master/lib/prettify.min.js"></script>
<script src="static/editor.md-master/lib/raphael.min.js"></script>
<script src="static/editor.md-master/lib/underscore.min.js"></script>
<script src="static/editor.md-master/lib/sequence-diagram.min.js"></script>
<script src="static/editor.md-master/lib/flowchart.min.js"></script>
<script src="static/editor.md-master/lib/jquery.flowchart.min.js"></script>
<script src="./static/editor.md-master/editormd.js"></script>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
<style>
*{
margin:0;
padding:0;
}
</style>
</html>
说明:这是vue 中的index.html 文件,引用了插件中的一些css和js文件,这些文件引用的顺序最好和我这个一样,因为一开始我引用这些文件的时候顺序是乱的,不是这个顺序,导致有些功能无法实现,但有一个东西是确定的,jqury.min.js文件的引用肯定是引用的js文件的第一个,因为editor.md这个插件是基于jquery的
2、 创建一个组件(新建一个vue文件)
test.vue
<template>
<div>
<div id="layout">
<div id="blog_editormd" style="margin-top: 5px;">
<textarea style="display: none;">[TOC]</textarea>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
blogEditor:{}
}
},
methods: {
},
created(){
var _this = this;
_this.$nextTick(() =>{
const blogEditor = editormd("blog_editormd",{
placeholder : '欢迎使用editor.md 编辑器',
width : "100%",
height : "880",
syncScrolling : "single",
emoji :true,
/* path : '../../../static/editor.md-master/lib/' ,*/
path : '/static/editor.md-master/lib/',
//pluginPath:'/plugins',
saveHTMLToTextarea : true,
tocm : true,
tex :true,
flowChart : true,
imageUpload : true,
imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL : "",
//crossDomainUpload : true
previewTheme: "dark"
/**设置主题颜色*/
/* editorTheme: "pastel-on-dark",
theme: "gray",
previewTheme: "dark"*/
});
//将刚刚定义的对象 存到vue中,用的时候再取出来
_this.blogEditor = blogEditor;
});
}
}
</script>
下面是完整的属性配置(具体的属性值有哪些可以百度,或上官网)
myEditor = editormd("my-editormd", {
width: "100%",
height: 740,
path: '/Content/editormd/lib/',
/**设置主题颜色*/
theme: "dark",
previewTheme: "dark",
editorTheme: "pastel-on-dark",
markdown: "",
codeFold: true,//折叠代码块
syncScrolling : 'single',
saveHTMLToTextarea: true, // 保存 HTML 到 Textarea
searchReplace: true,
watch : false, // 关闭实时预览
htmlDecode: "style,script,iframe|on*", // 开启 HTML 标签解析,为了安全性,默认不开启
//toolbar : false, //关闭工具栏
//previewCodeHighlight : false, // 关闭预览 HTML 的代码块高亮,默认开启
emoji: true,//emoji表情,默认关闭
taskList: true,
tocm: true, // Using [TOCM]
tex: true, // 开启科学公式TeX语言支持,默认关闭
flowChart: true, // 开启流程图支持,默认关闭
sequenceDiagram: true, // 开启时序/序列图支持,默认关闭,
//dialogLockScreen : false, // 设置弹出层对话框不锁屏,全局通用,默认为true
//dialogShowMask : false, // 设置弹出层对话框显示透明遮罩层,全局通用,默认为true
//dialogDraggable : false, // 设置弹出层对话框不可拖动,全局通用,默认为true
//dialogMaskOpacity : 0.4, // 设置透明遮罩层的透明度,全局通用,默认值为0.1
//dialogMaskBgColor : "#000", // 设置透明遮罩层的背景颜色,全局通用,默认为#fff
imageUpload: true,//图片上传
imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL: "/Center/RichTextUpload",//上传图片接口地址
//图片上传后的回调处理
onload: function () {
//console.log('onload', this);
//this.fullscreen();
//this.unwatch();
//this.watch().fullscreen();
//this.setMarkdown("#PHP");
//this.width("100%");
//this.height(480);
//this.resize("100%", 640);
}
});
!!!注意要配置路由
说明:有了这个组件,富文本就基本可以显示出来了,在组件的created()方法声明blogEditor ,blogEditor 后面的就是editor.md的配置,我用blogEditor接收了一下,这里有3个要注意的地方
1、 配置editor.md的属性要在dom加载完成之后进行配置,在普通的html页面中只要引入jquery,将配置写在script标签的(这是个美元符号,不晓得为什么显示不出来,下面的this.后面也是)
(
f
u
n
c
t
i
o
n
(
)
)
;
中
就
可
以
,
而
我
用
的
是
v
u
e
,
所
以
将
属
性
的
配
置
写
在
了
t
h
i
s
.
(function() {}); 中就可以,而我用的是vue ,所以将属性的配置写在了this.
(function());中就可以,而我用的是vue,所以将属性的配置写在了this.nextTick(() =>{}中,
2、 配置中可以看到,editor对象有两个参数,第一个是字符串,第二个是一个对象,要注意的是第一个参数,这个参数是组件中textarea 标签父元素的id
3、 配置editor.md属性的时候,属性中path这个属性是要注意的,这个属性的值就是插件中lib文件夹的相对路径,代码中有一行注释了的path,这个是我在本地运行时用到的一个相对路径,但打包发布后报404,这是因为vue项目打包后 就只有一个static文件夹,一个html文件,项目在访问的时候是直接访问static文件夹的,反正打包前根据组件相对定位是可以用的,具体的试下就晓得,我也记不太清了(这个路径在项目部署的时候还有一个坑,这个我写在另一篇文章中)
到此富文本的框就显示出来了,下面讲下怎么获取富文本中输入的内容
2、获取富文本中输入的内容以及插件根据内容生成的一些标签代码(html的)
注:这里用到了上边代码中的blogEditor 对象,我这里是直接把它存到了vue对象中,这样我在该组件的其他地方就可以使用blogEditor 进行一系列操作了
- 获取输入的内容(用户输入),var inputContent = _this.blogEditor.getMarkdown();
- 获取插件生成的html代码, var htmlContent = _this.blogEditor.getHTML(); 注意,要获取插件生成html代码要设置属性 saveHTMLToTextarea: true,
这些方法在源码中都有,也就是editormd.js文件,代码中对其中定义的方法也都写了注释,有兴趣的话可以看下
内容也获取到了,下面讲下富文本框上方的工具栏的使用及相关配置
这个图太大了,下面讲的话就只截工具栏
3、工具栏的使用及相关配置配置
1、自定义工具栏
这个我没有自定义,所以没什么说的,下面是官方给的例子
https://pandao.github.io/editor.md/examples/custom-toolbar.html
2、表情
(1)配置emoji: true 属性
(2)下载本地表情包 ,地址:https://github.com/SemiWarm/SemiWarmAdminPhotos/blob/master/emoji.zip
(3)将下载的表情包解压放到 插件目录/plugins/emoji-dialog/下面
(4)修改editormd.js 的emoji表情包路径
editormd.emoji = {
//path : "http://www.emoji-cheat-sheet.com/graphics/emojis/",
path : "/static/editor.md-master/lib/../plugins/emoji-dialog/emoji/",
ext : ".png"
};
//这个路径有点乱,我这样是可以访问到图片的,网上也有人这样写的
//path : "../markdown/plugins/emoji-dialog/emoji/", 反正能访问图片到就行
注意:我修改的是editormd.js,我引用的也是editormd.js. 如果要引用editormd.min.js,你需要把修改好了的editormd.js压缩成editormd.min.js再使用
3、表格及有序列表无序列表
这两个地方我碰到的问题是文章写好后,查看文章时发现这三个东西上面会解析出很多的p标签和br标签
解决方法:
https://github.com/pandao/editor.md/issues/656
上面这篇文章有解决方法,其实后面我发现editormd.js中有两处要改的地方(有两处breaks:true),具体的看上面链接的内容,我两处都改了,问题解决了,只改一个我没试过。
4、图片上传
如果要上传本地图片的话就要后台借口的配合了,插件对后台接口的返回值有要求,要求的是返回json格式的数据,下面是要求返回的字段
{
success : 0 | 1, //0表示上传失败;1表示上传成功
message : "提示的信息",
url : "图片地址" //上传成功时才返回
}
我用的是springboot,springboot默认返回的是json格式,所以我也没怎么去处理数据的格式,就直接返回了一个类,类里面封装了这三个属性。图片的正常上传这是肯定要实现的,不然其他别谈,图片正常上传后上传图片的那个dialog中第一个输入框就会显示你返回的那个图片地址(上面的url),这个时候你点确定dialog关闭图片是显示不出来的,除非你把图片上传到你的项目目录下(不建议将图片上传到项目目录下),我是将图片上传到盘符中的。具体怎么配置怎么做才能访问到上传到盘符后的图片,看大佬的,我是根据这位大佬的文章解决的这个问题,注意后台接口中的这个东西
@RequestParam(value = “editormd-image-file”, required = false) MultipartFile file
这个下面的文章中也有
https://blog.csdn.net/qq_26641781/article/details/80571264
这里还有一个大坑,图片上传的
现在流行前后端分离,像我这个项目就是这样的,前端和后端不在一起,这个时候你上传图片就会有一个跨域的问题,(报错跨域),这是因为你图片上传后返回的信息插件是给你放到一个iframe下(这个iframe的src就是后台的接口)的,再通过获取iframe元素来获取,前后端分离不用多讲,即使在同一台电脑上,前后端同时运行起来的端口是不可能相同的,这个时候就产生了一个跨域问题(正常情况下,浏览器是不允许在当前域获取另一个域的iframe内容的,如果你针对跨域这一块做了配置那是另外一回事)
解决方法
部署项目,前后端分别打包,把代码扔到一个服务器上去运行,这样就不会再报跨域了(在部署的时候有些东西也是要注意的,不然有些静态资源访问报404,这个我在另一篇文章会讲,慢慢摸索还是可以搞出来的)
5、黑色代码块
这个我也是看别人博客做的,我再叙述一遍也没有这个必要,下面贴出大佬的文章地址
https://www.cnblogs.com/Leo_wl/p/5763491.html
这里想再说点的就是,大佬提供了一个editormd.min.css文件,并不知道她改了哪些东西,虽然他解释了,如果不用黑色代码块的话用插件里的editormd.min.css就行,但要用的话改源码的样式就比较难了,因为
editormd.min.css是压缩了的,看不懂,所以后面调整源码样式的话就只有一个了,覆盖源码的样式,而覆盖源码的样式也有个要注意的地方,以我这个项目为例,我用的是vue, 在style标签有个属性scoped,覆盖的样式不能写在有scoped的style标签中,不然就不覆盖不成功
差点忘了,还有一个就是查看文章,我写的是一个博客项目,所以我就称呼为查看文章
6查看文章
在一开始的index.html中引入了很多的js文件,除了jquery ,editormd.js其他都是查看文章这一块才用到的文件,代码:
view.vue
<template>
<div>
<div id="layout">
<div id="articleView" >
<textarea style="display: none" name="editormd">{{article.contentHtml}}</textarea>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
article:{}
}
},
methods: {
getArticleDetail(){
var _this = this;
//var articleId = window.sessionStorage.getItem("articleId");
var articleId = _this.$route.params.articleId;
_this.$axios.post(`/data/article/detail/${articleId}`).then(res =>{
var code = res.data.code;
var message = res.data.message;
if(code === -1){
_this.$message.warning(message);
}else {
_this.article = res.data.responseData;
_this.$nextTick(()=>{
let editorView = editormd.markdownToHTML("articleView", {
htmlDecode : "style,script,iframe", // you can filter tags decode
emoji : true,
taskList : true,
tex : true, // 默认不解析
flowChart : true, // 默认不解析
sequenceDiagram : true, // 默认不解析
});
});
}
})
},
},
created() {
var _this = this;
_this.getArticleDetail();
}
}
</script>
我简单解释下上面的代码,在vue created方法中通过接口查到了要显示的文章信息(上面的textarea放通过getMarkDown(),getHTML()方法获取的内容好像都可以解析),然后再请求的回调中声明一个对象,也讲不出这是个啥,反正就是这样一个东西,跟显示富文本框差不多,至于要不要等DOM加载完成我没试过,我这样写没错,文章可以显示出来
_this.$nextTick(()=>{
let editorView = editormd.markdownToHTML("articleView", {
htmlDecode : "style,script,iframe", // you can filter tags decode
emoji : true,
taskList : true,
tex : true, // 默认不解析
flowChart : true, // 默认不解析
sequenceDiagram : true, // 默认不解析
});
});
7、编辑写好了文章
稍微的讲下这个,这个只要在配置、渲染富文本框的时候,在上面的textarea中双向绑定从数据库中查出来的内容信息就可以了,这是vue的东西,当然也可以用jquery 的 .val()方法将值赋给textarea
到此问题就记录完了
更多推荐
所有评论(0)