效果图
1587719278(1).jpg
main.js
import hljs from "highlight.js";
import "highlight.js/styles/atom-one-dark.css"; // 样式文件
Vue.directive("highlight", function(el) {
console.log("自定义指令", el);
let blocks = el.querySelectorAll("pre code");
blocks.forEach(block => {
console.log(block.innerHTML, "block是", block);
try {
let str = block.innerHTML;
let lang = "js";
// 得到经过highlight.js之后的html代码
const preCode = hljs.highlight(lang, str, true).value;
// 以换行进行分割
// const lines = preCode.split(/\n/).slice(0, -1);
const linesLength = preCode.split("<br></br>").length;
// 生成行号 aria-hidden 对浏览器语义化隐藏
let linesNum = '<span aria-hidden="true" class="line-numbers-rows">';
for (let index = 0; index < linesLength + 1; index++) {
linesNum = linesNum + "<span></span>";
}
linesNum += "</span>";
let html = preCode;
// 右上角语言说明
// if (linesLength) {
// html += '<b class="name">' + lang + "</b>";
// }
html =
'<pre class="hljs"><code>' + html + "</code>" + linesNum + "</pre>";
block.parentNode.parentNode.innerHTML = html;
} catch (__) {
console.log("执行错误", __);
}
// 方法一
// hljs.highlightBlock(block);
// const linesLength = block.innerHTML.split("<br></br>").length;
// // 生成行号 aria-hidden 对浏览器语义化隐藏
// let linesNum = '<span aria-hidden="true" class="line-numbers-rows">';
// for (let index = 0; index < linesLength + 1; index++) {
// linesNum = linesNum + "<span></span>";
// }
// linesNum += "</span>";
// block.parentNode.innerHTML = block.parentNode.innerHTML + linesNum;
});
});
父组件
<template>
<div class="page">
<div>
<p>{{ code.title }}</p>
<div v-highlight class="codes">
<render :render="code.render"> </render>
</div>
</div>
</div>
</template>
<script>
import render from "./render";
export default {
name: "",
components: {
render
},
data() {
// 两种换行都可以
const br = <br></br>; //{br}
const n = "\n"; //{n}
return {
code: {
title: "一个标题",
render: h => {
return (
<pre>
<code>
var str = "18127446988"
{n}
console.log(enStr)
</code>
</pre>
);
}
}
};
}
};
</script>
<style lang="scss">
.page {
text-align: center;
// 方法二
.codes {
width: 500px;
margin: 0 auto;
}
.hljs {
position: relative;
text-align: left;
padding: 7px 2px 7px 40px;
code {
display: block;
margin: 0 10px;
}
}
// 方法一
// .codes {
// width: 500px;
// margin: 0 auto;
// position: relative;
// background: #282c34;
// }
// pre {
// padding-left: 50px;
// }
// .hljs {
// text-align: left;
// }
// 共用
.line-numbers-rows {
position: absolute;
pointer-events: none;
top: 7px;
bottom: 7px;
left: 0;
font-size: 100%;
width: 40px;
text-align: center;
letter-spacing: -1px;
border-right: 1px solid rgba(0, 0, 0, 0.66);
user-select: none;
counter-reset: linenumber;
span {
pointer-events: none;
display: block;
counter-increment: linenumber;
&:before {
content: counter(linenumber);
color: #999;
display: block;
text-align: center;
}
}
}
}
</style>
子组件
<script>
export default {
name: "Render",
functional: true,
props: {
render: Function
},
render: (h, ctx) => {
return ctx.props.render ? ctx.props.render(h) : "";
}
};
</script>
网友评论