markdown浏览页加入目录导航

This commit is contained in:
jmal 2020-03-08 18:22:38 +08:00
parent e6573a5ed8
commit 17e573dfac
7 changed files with 370 additions and 99 deletions

View File

@ -0,0 +1 @@
<svg t="1583656348754" class="icon" viewBox="0 0 1639 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2476" width="200" height="200"><path d="M0 102.4C0 45.846047 45.451756 0 102.4 0 158.953953 0 204.8 45.451756 204.8 102.4 204.8 158.953953 159.348244 204.8 102.4 204.8 45.846047 204.8 0 159.348244 0 102.4ZM409.6 102.4C409.6 45.846047 456.269926 0 512.253266 0L1535.746734 0C1592.440566 0 1638.4 45.451756 1638.4 102.4 1638.4 158.953953 1591.730074 204.8 1535.746734 204.8L512.253266 204.8C455.559434 204.8 409.6 159.348244 409.6 102.4ZM0 512C0 455.446047 45.451756 409.6 102.4 409.6 158.953953 409.6 204.8 455.051756 204.8 512 204.8 568.553953 159.348244 614.4 102.4 614.4 45.846047 614.4 0 568.948244 0 512ZM409.6 512C409.6 455.446047 456.269926 409.6 512.253266 409.6L1535.746734 409.6C1592.440566 409.6 1638.4 455.051756 1638.4 512 1638.4 568.553953 1591.730074 614.4 1535.746734 614.4L512.253266 614.4C455.559434 614.4 409.6 568.948244 409.6 512ZM0 921.6C0 865.046047 45.451756 819.2 102.4 819.2 158.953953 819.2 204.8 864.651756 204.8 921.6 204.8 978.153953 159.348244 1024 102.4 1024 45.846047 1024 0 978.548244 0 921.6ZM409.6 921.6C409.6 865.046047 456.269926 819.2 512.253266 819.2L1535.746734 819.2C1592.440566 819.2 1638.4 864.651756 1638.4 921.6 1638.4 978.153953 1591.730074 1024 1535.746734 1024L512.253266 1024C455.559434 1024 409.6 978.548244 409.6 921.6Z" p-id="2477"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -126,13 +126,25 @@ export const constantRoutes = [
},
{
path: '/public/p',
path: '/public/article',
component: Layout,
children: [
{
path: '',
name: 'p',
component: () => import('@/views/public/p/index'),
name: 'article',
component: () => import('@/views/public/article/index'),
}
]
},
{
path: '/public/articles',
component: Layout,
children: [
{
path: '',
name: 'articles',
component: () => import('@/views/public/articles/index'),
meta: { title: '文档列表', icon: 'md-list' }
}
]

View File

@ -1423,7 +1423,7 @@ export default {
if(row.contentType.includes('text')){
// let routeData = this.$router.resolve({path: '/public/p',query: {mark: row.id}})
// window.open(routeData.href, '_blank');
this.$router.push(`/public/p?mark=${row.id}`)
this.$router.push(`/public/article?mark=${row.id}`)
}else{
// 打开文件
const fileIds = [row.id]

View File

@ -769,7 +769,7 @@
if(row.contentType.includes('text')){
// let routeData = this.$router.resolve({path: '/public/p',query: {mark: row.id}})
// window.open(routeData.href, '_blank');
this.$router.push(`/public/p?mark=${row.id}`)
this.$router.push(`/public/article?mark=${row.id}`)
}else{
// 打开文件
const fileIds = [row.id]

View File

@ -0,0 +1,176 @@
<template>
<div v-wechat-title="pageTitle">
<al-back-top></al-back-top>
<div class="content">
<el-row :gutter="0">
<el-col :xs="0" :sm="1" :md="4" :lg="5" :xl="6"><div style="color: white">c</div></el-col>
<el-col :xs="24" :sm="22" :md="16" :lg="14" :xl="12">
<el-main class="main-content">
<mavon-editor
ref="md"
v-if="!showList"
v-model="content"
:subfield="false"
:boxShadow="true"
:toolbarsFlag="false"
defaultOpen="preview"
/>
</el-main>
</el-col>
<el-col :xs="0" :sm="1" :md="4" :lg="5" :xl="6">
</el-col>
</el-row>
<div v-show="titleList.length > 0" class="right-bj">
<div class="slimScrollDiv" style="position: relative; overflow: hidden; width: auto; height: 662px;">
<div class="right-menu" id="inner-content-div" style="overflow: hidden; width: auto; height: 662px;">
<div class="toc-content">
<header class="toc-header"><svg-icon icon-class="contents"></svg-icon><span>目录</span></header>
</div>
<div class="j-titleList titleList">
<div class="j-bj" style="height: 40px; top: 0px;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import AlBackTop from "@/components/backtop/AlBackTop";
import markdownApi from '@/api/markdown-api'
import $ from 'jquery'
export default {
components: { AlBackTop },
data() {
return {
pageTitle: "文章列表",
showList: true,
toolbars: null,
toolbarsFlag: true,
content:'',
html:'',
titleList: []
}
},
mounted() {
console.log(777)
if(this.$route.query.mark){
this.getMarkDown()
this.showList = false
}
},
methods: {
onScroll() {
// console.log(document.documentElement.scrollTop)
},
getMarkDown() {
markdownApi.getMarkdown({
mark: this.$route.query.mark
}).then((res) => {
this.pageTitle = res.data.name
this.content = res.data.contentText
const _this = this
setTimeout(function () {
if (document.cookie.match(/scrollTop=([^;]+)(;|$)/) != null) {
var arr = document.cookie.match(/scrollTop=([^;]+)(;|$)/); //cookies中不为空,则读取滚动条位置
document.documentElement.scrollTop = parseInt(arr[1]);
document.body.scrollTop = parseInt(arr[1]);
}
},10)
this.$nextTick(()=>{ // DOM更新之后获取子元素
const hTag = document.querySelector("h1");
if(hTag){
this.pageTitle = hTag.innerText
}
let a = $('.el-main').html().match(/<h1.*?<\/h1>|<h2.*?<\/h2>/g);
if(a && a.length >0 ){
a = a.splice(a.length/2,a.length)
for (let i = 0; i < a.length; i++) {
a[i] = a[i].replace(/id="/g, 'href="#')
if (a[i].indexOf('h2') != -1) {
a[i] = '<li class="pl">' + a[i].replace(/<h2>|<\/h2>/g, '') + '</li>'
} else {
a[i] = '<li>' + a[i].replace(/<h1>|<\/h1>/g, '') + '</li>'
}
this.titleList.push(i)
}
$('.j-titleList').prepend(a)
//获取id数组
for (let i = 0; i < a.length; i++) {
a[i] = a[i].replace(/.*?#(.*)".*/g, '$1')
}
$(window).on("scroll",function () {
for (let i = 0; i < a.length; i++) {
if ($(window).scrollTop() > $('#' + a[i]).offset().top - 100 || $(this).scrollTop() + $(this).height() == $(document).height()) {
$('.j-titleList').find('li').eq(i).addClass('active').siblings('li').removeClass('active');
$('.j-bj').css('top', i * 44)
}
}
})
let $root = $('html, body');
$('.j-titleList li').on("click", function () {
$root.animate({
scrollTop: $($.attr(this.querySelector("a"), 'href')).offset().top - 20
}, 400);
return false
});
}
})
// const doc = document.querySelector(".v-show-content");
// document.addEventListener("scroll", _this.onScroll);
})
}
},
destroyed() {
$(window).unbind("scroll")
$('.j-titleList li').unbind("click");
}
}
</script>
<style lang="scss" scoped>
@import "src/styles/markdown";
/deep/ .v-note-wrapper {
position: unset;
}
@media only screen and (max-width: 768px){
.el-main {
padding: 20px 0px 20px 0px;
}
}
@media only screen and (min-width: 768px){
.el-main {
padding: 20px;
}
}
@media only screen and (min-width: 992px){
.el-main {
padding: 20px;
}
}
@media only screen and (min-width: 1200px){
.el-main {
padding: 20px;
}
}
@media only screen and (min-width: 1920px){
.el-main {
padding: 20px;
}
}
</style>

View File

@ -0,0 +1,176 @@
<template>
<div v-wechat-title="pageTitle">
<al-back-top></al-back-top>
<div class="content">
<el-row :gutter="0">
<el-col :xs="0" :sm="1" :md="4" :lg="5" :xl="6"><div style="color: white">c</div></el-col>
<el-col :xs="24" :sm="22" :md="16" :lg="14" :xl="12">
<el-main class="main-content">
<mavon-editor
ref="md"
v-if="!showList"
v-model="content"
:subfield="false"
:boxShadow="true"
:toolbarsFlag="false"
defaultOpen="preview"
/>
</el-main>
</el-col>
<el-col :xs="0" :sm="1" :md="4" :lg="5" :xl="6">
</el-col>
</el-row>
<div v-show="titleList.length > 0" class="right-bj">
<div class="slimScrollDiv" style="position: relative; overflow: hidden; width: auto; height: 662px;">
<div class="right-menu" id="inner-content-div" style="overflow: hidden; width: auto; height: 662px;">
<div class="toc-content">
<header class="toc-header"><svg-icon icon-class="contents"></svg-icon><span>目录</span></header>
</div>
<div class="j-titleList titleList">
<div class="j-bj" style="height: 40px; top: 0px;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import AlBackTop from "@/components/backtop/AlBackTop";
import markdownApi from '@/api/markdown-api'
import $ from 'jquery'
export default {
components: { AlBackTop },
data() {
return {
pageTitle: "文章列表",
showList: true,
toolbars: null,
toolbarsFlag: true,
content:'',
html:'',
titleList: []
}
},
mounted() {
console.log(777)
if(this.$route.query.mark){
this.getMarkDown()
this.showList = false
}
},
methods: {
onScroll() {
// console.log(document.documentElement.scrollTop)
},
getMarkDown() {
markdownApi.getMarkdown({
mark: this.$route.query.mark
}).then((res) => {
this.pageTitle = res.data.name
this.content = res.data.contentText
const _this = this
setTimeout(function () {
if (document.cookie.match(/scrollTop=([^;]+)(;|$)/) != null) {
var arr = document.cookie.match(/scrollTop=([^;]+)(;|$)/); //cookies中不为空,则读取滚动条位置
document.documentElement.scrollTop = parseInt(arr[1]);
document.body.scrollTop = parseInt(arr[1]);
}
},10)
this.$nextTick(()=>{ // DOM更新之后获取子元素
const hTag = document.querySelector("h1");
if(hTag){
this.pageTitle = hTag.innerText
}
let a = $('.el-main').html().match(/<h1.*?<\/h1>|<h2.*?<\/h2>/g);
if(a && a.length >0 ){
a = a.splice(a.length/2,a.length)
for (let i = 0; i < a.length; i++) {
a[i] = a[i].replace(/id="/g, 'href="#')
if (a[i].indexOf('h2') != -1) {
a[i] = '<li class="pl">' + a[i].replace(/<h2>|<\/h2>/g, '') + '</li>'
} else {
a[i] = '<li>' + a[i].replace(/<h1>|<\/h1>/g, '') + '</li>'
}
this.titleList.push(i)
}
$('.j-titleList').prepend(a)
//获取id数组
for (let i = 0; i < a.length; i++) {
a[i] = a[i].replace(/.*?#(.*)".*/g, '$1')
}
$(window).on("scroll",function () {
for (let i = 0; i < a.length; i++) {
if ($(window).scrollTop() > $('#' + a[i]).offset().top - 100 || $(this).scrollTop() + $(this).height() == $(document).height()) {
$('.j-titleList').find('li').eq(i).addClass('active').siblings('li').removeClass('active');
$('.j-bj').css('top', i * 44)
}
}
})
let $root = $('html, body');
$('.j-titleList li').on("click", function () {
$root.animate({
scrollTop: $($.attr(this.querySelector("a"), 'href')).offset().top - 20
}, 400);
return false
});
}
})
// const doc = document.querySelector(".v-show-content");
// document.addEventListener("scroll", _this.onScroll);
})
}
},
destroyed() {
$(window).unbind("scroll")
$('.j-titleList li').unbind("click");
}
}
</script>
<style lang="scss" scoped>
@import "src/styles/markdown";
/deep/ .v-note-wrapper {
position: unset;
}
@media only screen and (max-width: 768px){
.el-main {
padding: 20px 0px 20px 0px;
}
}
@media only screen and (min-width: 768px){
.el-main {
padding: 20px;
}
}
@media only screen and (min-width: 992px){
.el-main {
padding: 20px;
}
}
@media only screen and (min-width: 1200px){
.el-main {
padding: 20px;
}
}
@media only screen and (min-width: 1920px){
.el-main {
padding: 20px;
}
}
</style>

View File

@ -1,94 +0,0 @@
<template>
<div v-wechat-title="pageTitle">
<al-back-top></al-back-top>
<div class="content">
<el-row :gutter="0">
<el-col :xs="0" :sm="1" :md="3" :lg="5" :xl="6"><div style="color: white">c</div></el-col>
<el-col :xs="24" :sm="22" :md="18" :lg="14" :xl="12">
<el-main>
<mavon-editor
ref="md"
v-if="!showList"
v-model="content"
:subfield="false"
:boxShadow="true"
:toolbarsFlag="false"
defaultOpen="preview"
/>
</el-main>
</el-col>
<el-col :xs="0" :sm="1" :md="3" :lg="5" :xl="6"></el-col>
</el-row>
</div>
</div>
</template>
<script>
import AlBackTop from "@/components/backtop/AlBackTop";
import markdownApi from '@/api/markdown-api'
export default {
components: { AlBackTop },
data() {
return {
pageTitle: "文章列表",
showList: true,
toolbars: null,
toolbarsFlag: true,
content:'',
html:'',
}
},
mounted() {
if(this.$route.query.mark){
this.showList = false
}
this.getMarkDown()
},
methods: {
onScroll() {
// console.log(document.documentElement.scrollTop)
},
getMarkDown() {
markdownApi.getMarkdown({
mark: this.$route.query.mark
}).then((res) => {
console.log(res)
this.pageTitle = res.data.name
this.content = res.data.contentText
const _this = this
setTimeout(function () {
if (document.cookie.match(/scrollTop=([^;]+)(;|$)/) != null) {
var arr = document.cookie.match(/scrollTop=([^;]+)(;|$)/); //cookies中不为空,则读取滚动条位置
document.documentElement.scrollTop = parseInt(arr[1]);
document.body.scrollTop = parseInt(arr[1]);
}
},10)
this.$nextTick(()=>{ // DOM更新之后获取子元素
this.pageTitle = document.querySelector("h1").innerText
})
// const doc = document.querySelector(".v-show-content");
document.addEventListener("scroll", _this.onScroll);
})
}
}
}
</script>
<style lang="scss" scoped>
/deep/ .v-note-wrapper {
position: unset;
}
.content {
/*font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",*/
/*"Microsoft YaHei", "微软雅黑", Arial, sans-serif;*/
/*-webkit-font-smoothing: antialiased;*/
/*-moz-osx-font-smoothing: grayscale;*/
/*width: 100%;*/
/*height: 100%;*/
/*overflow-y: scroll;*/
}
</style>