【博客系列(一)】mavonEditor+highlight.js+highlightjs-line-numbers.js 新增mac样式+行数显示功能

该文详细介绍了如何在Vue项目中使用mavon-editor进行Markdown编辑,包括后台将markdown内容保存至数据库、图片上传处理,以及前端展示markdown内容并实现代码高亮和行号显示。同时,文章还展示了如何定制mac样式的代码高亮效果。
摘要由CSDN通过智能技术生成

【一】vue的mavon-editor使用

1、 后台管理部分:

【知识点】 后台管理项目保存好的mavon-editor的markdown格式到数据库

【1.1】先安装mavon-editor

npm install mavon-editor

【1.2】在main.js全局引入使用

import mavonEditor from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'
Vue.use(mavonEditor)

【1.3】vue项目中引入即可

<el-row>
    <mavon-editor :ishljs="true" ref="md" v-model="form.content" @imgAdd="addImg"   />
</el-row>

【1.4】mavon-editor中 上传图片功能实现

【知识点】@imgAdd 主要是监听图片上传事件,当你上传图片的时候,就会自动调用这个函数。一般来说,在使用富文本的时候,如果存在图片,我们在上传的时候,需要先传给后端,后端返回图片在数据库中的地址,我们再把地址回显出来。
<script>
	import { uploadImg } from '@/api/content/upload'
	export default {
	  name: 'Write',
	  data() {
	    return {
	      form: {
	        //mavon-editor 内容 
	        content: ''
	      },
	    },
	  methods: {  
	  // 绑定【@imgAdd】 event
	    addImg(pos, file) {
	      // 将图片上传到服务器.
	      uploadImg(file).then(response => {
	      // 将后端返回的url放在md中图片的指定位置
	        this.$refs.md.$img2Url(pos, response)
	      }).catch(error => {
	        this.$message.error(error.msg)
	      })
	    }
	  },
</script>
在【api/content/upload】中定义 uploadImg方法
import request from '@/utils/request'
export function uploadImg(img) {
  const formData = new FormData()
  formData.append('img', img)
  return request({
    url: '/upload',
    headers: { 'Content-Type': 'multipart/form-data' },
    method: 'post',
    data: formData
  })
}
如果是写一个小功能可以不定义uploadImg方法,参考以下代码即可
 imgAdd(pos, $file) {
      //新建form表单类型的数据
      let formData = new FormData();
      //将我们上传的图片地址$file加进表单里面,命名为“file”(参数名字与后端相匹配)
      formData.append("file", $file);
      console.log(formData);
      axios({
        url: this.$api + "icommunity/post/getImageUrl", //请求地址
        method: "POST",
        data: formData,
        headers: { "Content-Type": "multipart/form-data" },
      }).then((res) => {
        if (res.status === 200) {
       // 将后端返回的url放在md中图片的指定位置
          this.$refs.md.$img2Url(pos, res.data.data);
        } else {
          this.$message.error(res.message);
        }
      });
      //访问后台服务器方法
    },
博客声明【 本博客主要是用以本人学习总结,方便以后查阅; 本博客的博文并非全部由本人所创作,部分来自搜集的网络文章;鉴于本人水平一般,能力有限,仅限学习、交流,博文中不正之处,望谅解,欢迎大家文明建议和谐讨论】

2、前台展示部分:

【知识点】数据库存储数据为md文件,前端如果要展示需要转译为html文件。
如果前后台是一个项目无需再次安装mavon-editor,如果不是,请再次安装和引入mavon-editor,同样【marked】也可以完成转译为html文件,可自行进行使用

【2.1】先安装mavon-editor

npm install mavon-editor

【2.2】在main.js全局引入使用

import mavonEditor from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'
Vue.use(mavonEditor)

【2.3】组件中使用

<div class="markdown-body" v-html="detailObj.content" ></div>
<script>
import { mavonEditor } from 'mavon-editor'
    export default {
            methods: { 
                getArticleDetail:function(){
	                getArticle(this.aid).then((response)=>{
	                    this.detailObj = response
	                     const markdownIt = mavonEditor.getMarkdownIt()
	                    // markdownIt.render 完成转译为html文件
	                    this.detailObj.content = markdownIt.render(response.content);
	                })
            },
        }
     }    

【二】实现代码高亮 + 显示代码行号

1、实现代码高亮

【1.1】安装 highlight.js

// 用于代码高亮显示
npm install highlight.js

【1.2】在main.js全局引入使用

import hljs from 'highlight.js';
Vue.use(hljs);

【1.3】在main.js 中 封装成一个指令,highlight是指令的名称

import hljs from 'highlight.js';
Vue.use(hljs);

// 增加自定义命令v-highlight
Vue.directive("highlight", function (el) {
  let blocks = el.querySelectorAll("pre code");
  blocks.forEach(block => {
    hljs.highlightBlock(block);
  });
});
// 增加组定义属性,用于在代码中预处理代码格式
Vue.prototype.$hljs = hljs;

【1.4】在组件中使用 即添加 v-highlight

<div class="markdown-body" v-highlight v-html="detailObj.content" ></div>

2、实现显示代码行号

【2.1】安装 highlight.js

// 代码行号显示插件
npm install highlightjs-line-numbers.js

【2.2】在main.js 中 封装成一个指令 即添加 hljs.lineNumbersBlock(block);

import hljs from 'highlight.js';
Vue.use(hljs);

// 增加自定义命令v-highlight
Vue.directive("highlight", function (el) {
  let blocks = el.querySelectorAll("pre code");
  blocks.forEach(block => {
    hljs.highlightBlock(block);
    hljs.lineNumbersBlock(block);
  });
});
// 增加组定义属性,用于在代码中预处理代码格式
Vue.prototype.$hljs = hljs;
【知识点】实际使用的时候发现添加会发现冲突,失去效果
解决办法:copy highlightjs-line-numbers.js的源码到utils中,然后 修改后的源码结构,将highlightjs-line-numbers.js的源码【全选剪切】到function lineNumberInit(hljs, w, d) {}中,然后对外暴漏 export { lineNumberInit };
function lineNumberInit(hljs, w, d) {原内容。。。}
export { lineNumberInit };
然后w.hljs替换为hljs
if (hljs) {
    hljs.initLineNumbersOnLoad = initLineNumbersOnLoad;
    hljs.lineNumbersBlock = lineNumbersBlock;
    hljs.lineNumbersValue = lineNumbersValue;

    addStyles();
  } else {
    w.console.error("highlight.js not detected!");
  }

【2.2】修改 在main.js 中 指令,引入修改后的highlightjs-line-numbers.js


// 引入 highlight.js 代码高亮工具
import hljs from "highlight.js";
// 使用样式,有多种样式可选
import 'highlight.js/styles/atom-one-dark.css';
import { lineNumberInit } from "./utils/highlightjs-line-numbers.js";
lineNumberInit(hljs, window, window.document);
// 增加自定义命令v-highlight
Vue.directive("highlight", function (el) {
  let blocks = el.querySelectorAll("pre code");
  blocks.forEach(block => {
    hljs.highlightBlock(block);
    hljs.lineNumbersBlock(block);
  });
});
// 增加组定义属性,用于在代码中预处理代码格式
Vue.prototype.$hljs = hljs;

【三】实现mac样式

在这里插入图片描述

【1.1】找到 node_modules\highlight.js\styles\下 新建mac.css,然后将样式复制进去。

/*codecopy*/
.codecopy-btn {position: absolute;transition: all 0.5s;top: 10px;right: 20px;width: 90px;border-radius: 5px;background-color: rgba(221,221,221,.1);color: #999;text-align: center;font-weight: 700;font-size: 14px}
.codecopy-btn:hover {background-color: rgba(221,221,221,.2);top:9px}
/*语法高亮*/
.hljs{position:relative;display:block;overflow-x:hidden;background:#21252B;color:#999;padding:30px 5px 2px 5px;box-shadow: 0 10px 30px 0px rgb(0 0 0 / 40%)}
.hljs::before{content:"";position:absolute;left:15px;top:10px;overflow:visible;width:12px;height:12px;border-radius:16px;box-shadow:20px 0 #fdbc40, 40px 0 #35cd4b;-webkit-box-shadow:20px 0 #fdbc40, 40px 0 #35cd4b;background-color:#fc625d;white-space:nowrap;text-indent: 75px;font-size: 16px;line-height: 12px;font-weight: 700}
.hljs-ln{display:inline-block;overflow-x:auto;padding-bottom:5px}
.hljs-ln td {padding: 0;background-color: #21252B}
.hljs-ln::-webkit-scrollbar {height: 10px;border-radius: 5px;background: #333;}
.hljs-ln::-webkit-scrollbar-thumb {background-color: #bbb;border-radius: 5px;}
.hljs-ln::-webkit-scrollbar-thumb:hover {background: #ddd;}
.hljs table tbody tr{border:none}
.hljs .hljs-ln-line {padding: 1px 10px;border:none}
td.hljs-ln-line.hljs-ln-numbers {border-right: 1px solid #666;}
.hljs-keyword,.hljs-literal,.hljs-symbol,.hljs-name{color:#569cd6}
.hljs-link{color:#569cd6;text-decoration:underline}
.hljs-built_in,.hljs-type{color:#4ec9b0}
.hljs-number,.hljs-class{color:#b8d7a3}
.hljs-string,.hljs-meta-string{color:#d69d85}
.hljs-regexp,.hljs-template-tag{color:#9a5334}
.hljs-subst,.hljs-function,.hljs-title,.hljs-params,.hljs-formula{color:#dcdcdc}
.hljs-comment,.hljs-quote{color:#57a64a;font-style:italic}
.hljs-doctag{color:#608b4e}
.hljs-meta,.hljs-meta-keyword,.hljs-tag{color:#9b9b9b}
.hljs-variable,.hljs-template-variable{color:#bd63c5}
.hljs-attr,.hljs-attribute,.hljs-builtin-name{color:#9cdcfe}
.hljs-section{color:gold}
.hljs-emphasis{font-style:italic}
.hljs-strong{font-weight:bold}
.hljs-bullet,.hljs-selector-tag,.hljs-selector-id,.hljs-selector-class,.hljs-selector-attr,.hljs-selector-pseudo{color:#d7ba7d}
.hljs-addition{background-color:#144212;display:inline-block;width:100%}
.hljs-deletion{background-color:#600;display:inline-block;width:100%}
.hljs.language-html::before,.hljs.language-xml::before{content:"HTML/XML"}
.hljs.language-javascript::before{content:"JavaScript"}
.hljs.language-c::before{content:"C"}
.hljs.language-cpp::before{content:"C++"}
.hljs.language-java::before{content:"Java"}
.hljs.language-asp::before{content:"ASP"}
.hljs.language-actionscript::before{content:"ActionScript/Flash/Flex"}
.hljs.language-bash::before{content:"Bash"}
.hljs.language-css::before{content:"CSS"}
.hljs.language-asp::before{content:"ASP"}
.hljs.language-cs::before,
.hljs.language-csharp::before{content:"C#"}
.hljs.language-d::before{content:"D"}
.hljs.language-golang::before,.hljs.language-go::before{content:"Go"}
.hljs.language-json::before{content:"JSON"}
.hljs.language-lua::before{content:"Lua"}
.hljs.language-less::before{content:"LESS"}
.hljs.language-md::before,
.hljs.language-markdown::before,
.hljs.language-mkdown::before,
.hljs.language-mkd::before{content:"Markdown"}
.hljs.language-mm::before,
.hljs.language-objc::before,
.hljs.language-obj-c::before,
.hljs.language-objective-c::before{content:"Objective-C"}
.hljs.language-php::before{content:"PHP"}
.hljs.language-perl::before,
.hljs.language-pl::before,
.hljs.language-pm::before{content:"Perl"}
.hljs.language-python::before,
.hljs.language-py::before,
.hljs.language-gyp::before,
.hljs.language-ipython::before{content:"Python"}
.hljs.language-r::before{content:"R"}
.hljs.language-ruby::before,
.hljs.language-rb::before,
.hljs.language-gemspec::before,
.hljs.language-podspec::before,
.hljs.language-thor::before,
.hljs.language-irb::before{content:"Ruby"}
.hljs.language-sql::before{content:"SQL"}
.hljs.language-sh::before,
.hljs.language-shell::before,
.hljs.language-Session::before,
.hljs.language-shellsession::before,
.hljs.language-console::before{content:"Shell"}
.hljs.language-swift::before{content:"Swift"}
.hljs.language-vb::before{content:"VB/VBScript"}
.hljs.language-yaml::before{content:"YAML"}

【1.2】修改 在main.js 中 指令,修改为import ‘highlight.js/styles/mac.css’;


// 引入 highlight.js 代码高亮工具
import hljs from "highlight.js";
// 使用样式,有多种样式可选
import 'highlight.js/styles/mac.css';
import { lineNumberInit } from "./utils/highlightjs-line-numbers.js";
lineNumberInit(hljs, window, window.document);
// 增加自定义命令v-highlight
Vue.directive("highlight", function (el) {
 let blocks = el.querySelectorAll("pre code");
 blocks.forEach(block => {
   hljs.highlightBlock(block);
   hljs.lineNumbersBlock(block);
 });
});
// 增加组定义属性,用于在代码中预处理代码格式
Vue.prototype.$hljs = hljs;
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值