的编辑器用的是editor.md,但是有个缺点就是,插入的a链接不能从新标签打开,为了实现超链接从新标签打开,我还是费了几分钟的功夫的,下面是实现方式。
实现效果:点击查看
实现逻辑:当editormd初始化后,利用js获取a标签,并加上_target='blank'
<script>
//markdown 转换 js代码
$(function () {
var testEditormdView, testEditormdView2;
testEditormdView2=editormd.markdownToHTML("test-editormd", {
htmlDecode: "style,script,iframe", // you can filter tags decode
emoji: true,
taskList: true,
tex: true, // 默认不解析
flowChart: true, // 默认不解析
sequenceDiagram: true, // 默认不解析
});
//新窗口打开
//var links=document.links;
var links=$("#test-editormd a");
console.log(links)
for (var i=0; i < links.length; i++) {
// if (links[i].hostname !=window.location.hostname) {
// links[i].target='_blank';
// }
links[i].target='_blank';
console.log(links[i])
}
});
</script>
以上代码有部分冗余,其实是实现了2中途径,大家可以选择合适的,然后删除其他的代码。
TML是超文本标记语言的缩写,可能是当今网络上使用最多的标记语言。Markdown 在我们程序界也是一个必备的技能。我们可以使用 makrdown来渲染文本,它实际上是一种更快的写作方式,因为它学习成本很低,不需要掌握很多知识就可以开始。如果你的想写博客,甚至想作为技术作家写作时,Markdown 是你首先的写作工具。
本文主要介绍如果在 Vue 中使用 Markdown,废话说了很多了,我们就这开始按摩。
Vue 没有像React 那么多 MD 的插件。如 markdown-it、Remark.js、marked.js。希望在未来,会有更多好用的库来支持我们的 Vue ,经过一番调研,我选择了marked.js,因为它的星星最多,bug 少。
我们使用 vue-cli 来创建项目,运行如下命令:
vue create marked-example
这里我们选择最简单的 Vue2 模板创建项目,创建完后的项目结构如下:
+-- src/i
| +-- assets/
| +-- components
| +-- HelloWorld.vue
| +-- App.vue
| +-- main.js
现在我们在 MD 语法写个标题
<template>
<div>
{{ markdown }}
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
markdown: " # hello world ",
};
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
运行:
基于上面的代码,我们希望# hello world MD 语法能在 Vue 渲染成标题。要怎么做呢,这就需要借助 Marked.js 库。
Marked 或 marked.js 是一个低级别的编译器,帮助我们将 Markdowns 转换成HTML。安装一波试试水:
npm install marked
然后,在 app.vue 中引入:
import marked from 'marked';
渲染方法很简单就是把我们的文本传入 marked,结果返回是带了标签的文本内容,我们在用 v-html 渲染即可。
<template>
<!-- {{ markdown }} -->
<textarea v-model="markdown"></textarea>
<div v-html="markdownToHtml"></div>
</template>
<script>
import marked from 'marked';
export default {
name: 'App',
data(){
return {
markdown: "# Hello World",
};
},
computed: {
markdownToHtml(){
return marked(this.markdown);
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
这里我们多写了一个 textarea 标签,然后用了计算属性来实时的渲染 markdowns。运行后的结果如下
然后,多输入 一些 MD 语法验证一下:
当我们不想每个组件都 引入一次时,就可以声明成全局的。怎么做?
实现 marked 库全局化的方法是使用 Mixins。Mixins 只是Vue组件中可重复使用的功能的一个分布。
重构一下我们的 main.js 代码,如下所示:
import {createApp} from 'vue';
import App from './App.vue';
import marked from 'marked';
const markedMixin={
methods: {
md: function (input) {
return marked (input);
},
},
};
createApp(App).mixin(markedMixin).mount('#app')
当想转换 md时,直接在组件中调用 this.md 就可以将 md 转成 html 了。
~完,本文内容很简单,因为最近也用到类似的功能,搜索这个库,所以就分享一下,我是刷碗智,
现在回家做饭去了,我们下期再见!
作者:Dmitri Pavlutin 译者:前端小智 来源:blog.openreplay 原谅:https://blog.openreplay.com/how-parse-and-render-markdown-in-vuejs
们经常可以看到各个博客网站中用于编辑文章的富文本编辑器,在富文本编辑器中,我们可以对我们的编辑内容样式进行设置。富文本编辑器一般是通过插件来实现的,我们只需要在页面中配置一下插件提供的一些API即可。
本例中使用Editormd来演示如何配置使用富文本编辑器。
Editormd简介
Editormd是国内开源的一款在线Markdown编辑器,可嵌入的 Markdown 在线编辑器(组件),基于 CodeMirror、jQuery 和 Marked 构建。
支持“标准”Markdown / CommonMark和Github风格的语法,也可变身为代码编辑器。
官网地址:https://pandao.github.io/editor.md/
创建文章表
在使用富文本编辑器之前,先来创建一个文章表article,这里只添加了最基本的几个字段, 以后想要扩展的话还可以添加标签、时间、浏览量、点赞、评论等字段。建表SQL如下:
CREATE TABLE article(
id int(10) NOT NULL AUTO_INCREMENT COMMENT '文章唯一id',
author varchar(50) NOT NULL COMMENT '作者',
title varchar(100) NOT NULL COMMENT '标题',
content longtext NOT NULL COMMENT '文章内容'
PRIMARY KEY (id)
)ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
建完表,我们就可以开始编写代码来使用富文本编辑器了。
配置使用
1、创建一个SpringBoot项目,配置数据库连接,我们这里连接的是MyBatis(注意MySQL8需要在url中配置时区)。
spring:
datasource:
username: root
password: 123456
#?serverTimezone=UTC解决时区的报错
url: jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
thymeleaf:
cache: false
?
mybatis:
mapper-locations: classpath:com/wunian/mapper/*.xml
type-aliases-package: com.wunian.pojo
2、导入Editormd静态资源,静态资源的目录结构如下图所示。
3、编写文章编辑页面editor.html,引入Editormd的CSS和js文本,添加Editormd配置。
<!DOCTYPE html>
<html class="x-admin-sm" lang="zh" xmlns:th="http://www.thymeleaf.org">
?
<head>
<meta charset="UTF-8">
<title>及时雨的Blog</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" />
<!--Editor.md-->
<link rel="stylesheet" th:href="@{/editormd/css/editormd.css}"/>
<link rel="shortcut icon" href="https://pandao.github.io/editor.md/favicon.ico" type="image/x-icon" />
</head>
<!--写博客页面-->
<body>
?
<div class="layui-fluid">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<!--博客表单-->
<form name="mdEditorForm">
?
<div>
标题: <input type="text" name="title">
</div>
?
<div>
作者: <input type="text" name="author">
</div>
?
<!-- 文章的主体内容 textarea -->
<div id="article-content">
<textarea name="content" id="content" style="display:none;"> </textarea>
</div>
?
</form>
?
</div>
</div>
</div>
</body>
?
<!--editormd-->
<script th:src="@{/editormd/jquery.min.js}"></script>
<script th:src="@{/editormd/editormd.js}"></script>
?
<script type="text/javascript">
var testEditor;
$(function() {
//这是一个最简单的Editormd配置,往后我们要修改Editormd的
//功能或者样式,就改这里的配置就可以了
testEditor=editormd("article-content", {
width : "90%",
height : 640,
syncScrolling : "single",
path : "../editormd/lib/"
});
</script>
</html>
4、上面配置的只是最简单的富文本编辑器功能,我们可以添加更多的配置来增加功能。
<script type="text/javascript">
var testEditor;
?
//window.onload=function(){ }
$(function() {
testEditor=editormd("article-content", {
width : "95%",
height : 500,
syncScrolling : "single",
path : "../editormd/lib/",
// 自定义的增强配置!
saveHTMLToTextarea : true, // 保存 HTML 到 Textarea
emoji: true, // 开启表情的功能! 图片的本地配置!
// theme: "light",//工具栏主题
// previewTheme: "dark",//预览主题
// editorTheme: "pastel-on-dark",//编辑主题
// markdown的配置!
tex : true, // 开启科学公式TeX语言支持,默认关闭
flowChart : true, // 开启流程图支持,默认关闭
sequenceDiagram : true, // 开启时序/序列图支持,默认关闭,
//图片上传
imageUpload : true,
imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL : "/article/file/upload", // 文件上传的处理请求!
onload : function() {
console.log('onload', this);
},
/*指定需要显示的功能按钮*/
toolbarIcons : function() {
return ["undo","redo","|",
"bold","del","italic","quote","ucwords","uppercase","lowercase","|",
// "h1","h2","h3","h4","h5","h6","|",
"list-ul","list-ol","hr","|",
"link","reference-link","image","code","preformatted-text",
"code-block","table","datetime","emoji","html-entities","pagebreak","|",
"goto-line","watch","preview","fullscreen","clear","search","|",
//"help","info",
"releaseIcon", "index"]
},
// 这里的自定义功能就好比,Vue 组件
?
/*自定义功能按钮,下面我自定义了2个,一个是发布,一个是返回首页*/
toolbarIconTexts : {
releaseIcon : "<span bgcolor=\"gray\">发布</span>",
index : "<span bgcolor=\"red\">返回首页</span>",
},
?
/*给自定义按钮指定回调函数*/
toolbarHandlers:{
releaseIcon : function(cm, icon, cursor, selection) {
//表单提交
mdEditorForm.method="post";
mdEditorForm.action="/article/addArticle";//提交至服务器的路径
mdEditorForm.submit();
},
index : function(){
window.location.href='/';
},
}
});
});
</script>
5、由于表情包的加载地址在国外,因此有时候可能加载不出来,我们可以把表情包下载到本地,放到/static/editormd/plugins/emoji-dialog/emoji目录下,并修改editormd.js中的表情加载路径为我们的表情包存放的目录路径。
editormd.emoji ={
path : "../editormd/plugins/emoji-dialog/emoji/",
ext : ".png"
};
6、上传图片功能需要进行配置,我们可以在当前项目目录下建立upload文件夹来上传文件(注意这里应该手动建立目录,不要使用代码创建),然后配置一下虚拟路径(需要自定义WebMVC配置类)。
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
?
?
// 文件保存在真实目录/upload/下,
// 访问的时候使用虚路径/upload,比如文件名为1.png,就直接/upload/1.png就ok了。
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/upload/**")
.addResourceLocations("file:"+System.getProperty("user.dir")+"/upload/");
}
}
7、在Controller中编写文件上传的请求方法。
// MarkDown博客图片上传问题
@RequestMapping("/file/upload")
@ResponseBody
public JSONObject fileUpload(@RequestParam(value="editormd-image-file", required=true) MultipartFile file, HttpServletRequest request) throws IOException {
//上传路径保存设置
?
//获得SpringBoot当前项目的路径:System.getProperty("user.dir")
String path=System.getProperty("user.dir")+"/upload/";
?
//按照月份进行分类:
Calendar instance=Calendar.getInstance();
String month=(instance.get(Calendar.MONTH) + 1)+"月";
path=path+month;
?
File realPath=new File(path);
if (!realPath.exists()){
realPath.mkdirs();
}
?
//上传文件地址
System.out.println("上传文件保存地址:"+realPath);
?
//解决文件名字问题:我们使用uuid;
String filename="ks-"+UUID.randomUUID().toString().replaceAll("-", "")+".jpg";
//通过CommonsMultipartFile的方法直接写文件(注意这个时候)
file.transferTo(new File(realPath +"/"+ filename));
?
//给editormd进行回调
JSONObject res=new JSONObject();
res.put("url","/upload/"+month+"/"+ filename);
res.put("success", 1);
res.put("message", "upload success!");
?
return res;
}
8、编写文章显示页面article.html,同样需要配置Editormd来正常显示一些MarkDown文本。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title th:text="${article.title}"></title>
</head>
<!--读博客的页面-->
?
<body>
<div>
<!--文章头部信息:标题,作者,最后更新日期,导航-->
<h2 style="margin: auto 0" th:text="${article.title}"></h2>
作者:<span style="float: left" th:text="${article.author}"></span>
<!--文章主体内容-->
<div id="doc-content">
<textarea style="display:none;" placeholder="markdown" th:text="${article.content}"></textarea>
</div>
?
</div>
?
<!--固定editormd依赖! -->
<link rel="stylesheet" th:href="@{/editormd/css/editormd.preview.css}"/>
<script th:src="@{/editormd/jquery.min.js}"></script>
<script th:src="@{/editormd/lib/marked.min.js}"></script>
<script th:src="@{/editormd/lib/prettify.min.js}"></script>
<script th:src="@{/editormd/lib/raphael.min.js}"></script>
<script th:src="@{/editormd/lib/underscore.min.js}"></script>
<script th:src="@{/editormd/lib/sequence-diagram.min.js}"></script>
<script th:src="@{/editormd/lib/flowchart.min.js}"></script>
<script th:src="@{/editormd/lib/jquery.flowchart.min.js}"></script>
<script th:src="@{/editormd/editormd.js}"></script>
?
<script type="text/javascript">
var testEditor;
$(function () {
// 绑定我们要渲染页面的 div
testEditor=editormd.markdownToHTML("doc-content", {//注意:这里是上面DIV的id
htmlDecode: "style,script,iframe",
emoji: true,
taskList: true,
tocm: true,
tex: true, // 默认不解析
flowChart: true, // 默认不解析
sequenceDiagram: true, // 默认不解析
codeFold: true
});
});
</script>
</body>
</html>
9、最后别忘了编写保存文章和显示文章的Controller请求方法。
*请认真填写需求信息,我们会在24小时内与您取得联系。