的編輯器用的是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小時內與您取得聯系。