如何用网站做推广最新实时新闻
先上效果图
如图所示,在网页中,能直接解析markdown文档,并且生成目录大纲,也支持点击目录标题跳转到对应栏目中,下面就来讲讲是如何实现此功能的。
1、下载vue-markdown
yarn add vue-markdown
2、在页面中渲染markdown文件
<template><div><VueMarkdownclass="api-content":source="markdownContent"id="content"/></div>
</template><script>
import VueMarkdown from "vue-markdown";export default {components: {VueMarkdown,},data() {return {markdownContent: "",};},mounted() {this.loadMarkdownFile();},methods: {async loadMarkdownFile() {try {// api.md文件存放在根目录下的public文件夹中const response = await fetch("/api.md");const markdownText = await response.text();this.markdownContent = markdownText;} catch (error) {console.error("Failed to load the Markdown file:", error);}}, },
};
</script>
此时,打开浏览器查看,页面中已经正常渲染markdown文件了。
3、生成目录大纲
现在,我们需要有目录大纲方便我们查看文档。我的思路是,首先拿到markdown文件的html结构,然后找到所有H1-H5的标题标签,并给这些标签设置id,生成一个新数组,通过这个数组生成目录结构,说干就干。
//html部分<div class="api-tree" id="tree"><el-tree:data="tree":default-expand-all="true"@node-click="handleNodeClick"></el-tree>
</div>// js部分
catalogTree() {const content = document.getElementById("content").children;var arr = [];let currentHightestLevel;let parentId;let index = 0;for (let i = 0; i < content.length; i++) {let header = content[i].localName;if (/\b[h][0-9]\b/.test(header)) {let ele = $(content[i]);let name = ele.text();// 设置idele.attr("id", i);let id = i;if (index === 0 || header <= currentHightestLevel) {currentHightestLevel = header;parentId = id;}arr.push({id: id,label: name,parentId: parentId == id ? "0" : parentId,});index++;}}const tree = [];arr.forEach((item) => {if (item.parentId === "0") {tree.push(this.convertArrayToTree(arr, item));}});this.tree = tree;
},
convertArrayToTree(arr, node) {for (let i = 0; i < arr.length; i++) {if (arr[i].parentId === node.id) {const res = this.convertArrayToTree(arr, arr[i]);if (node.children) {node.children.push(res);} else {node.children = [res];}}}return node;
},
handleNodeClick(data) {let anchorElement = document.getElementById(data.id);if (anchorElement) {anchorElement.scrollIntoView({behavior: "smooth",block: "end",});}
},
4、大功告成,最后,附上全部代码,带css样式
<template><div class="page-api" id="myElement"><div class="api-tree" id="tree"><el-tree:data="tree":default-expand-all="true"@node-click="handleNodeClick"></el-tree></div><VueMarkdownclass="api-content":source="markdownContent"id="content"/></div>
</template><script>
import VueMarkdown from "vue-markdown";
import $ from "jquery";export default {components: {VueMarkdown,},data() {return {markdownContent: "",tree: [],};},mounted() {this.loadMarkdownFile();},methods: {async loadMarkdownFile() {try {const response = await fetch("/api.md");const markdownText = await response.text();this.markdownContent = markdownText;this.$nextTick(() => {this.catalogTree();});} catch (error) {console.error("Failed to load the Markdown file:", error);}},catalogTree() {const content = document.getElementById("content").children;var arr = [];let currentHightestLevel;let parentId;let index = 0;for (let i = 0; i < content.length; i++) {let header = content[i].localName;if (/\b[h][0-9]\b/.test(header)) {let ele = $(content[i]);let name = ele.text();// 设置idele.attr("id", i);// let id = ele.children("a").attr("id");let id = i;if (index === 0 || header <= currentHightestLevel) {currentHightestLevel = header;parentId = id;}arr.push({id: id,label: name,parentId: parentId == id ? "0" : parentId,});index++;}}const tree = [];arr.forEach((item) => {if (item.parentId === "0") {tree.push(this.convertArrayToTree(arr, item));}});this.tree = tree;},convertArrayToTree(arr, node) {for (let i = 0; i < arr.length; i++) {if (arr[i].parentId === node.id) {const res = this.convertArrayToTree(arr, arr[i]);if (node.children) {node.children.push(res);} else {node.children = [res];}}}return node;},handleNodeClick(data) {let anchorElement = document.getElementById(data.id);let scrollPosition = anchorElement.offsetTop - 20;let myElement = document.getElementById("myElement");myElement.scrollTo({left: 0,top: scrollPosition,behavior: "smooth",});// if (anchorElement) {// anchorElement.scrollIntoView({// behavior: "smooth",// block: "end",// });// }},},
};
</script><style lang="scss">
.page-api {display: flex;height: 100%;overflow-y: scroll;.api-tree {position: fixed;left: 20px;top: 120px;width: 200px;height: calc(100% - 160px);overflow-y: scroll;z-index: 99;.el-tree {background: none;color: #fff;.el-tree-node:focus > .el-tree-node__content,.el-tree-node__content:hover {background: none;color: rgb(24, 144, 255);}}}.api-content {flex: 1;margin-left: 220px;padding: 0 30px;color: rgba(255, 255, 255, 0.75);h3 {margin-left: 25px;}code {border-radius: 2px;color: #e96900;margin: 0 2px;padding: 3px 5px;white-space: pre-wrap;}table {border-collapse: collapse;border-spacing: 0;th,td {border: 1px solid #ddd;padding: 6px 13px;margin: 0;}}pre {background: rgba(0, 0, 0, 0.7);padding: 20px 30px;}}
}
</style>