添加文章页的 面包屑 和 文章信息栏

This commit is contained in:
xugaoyi 2020-03-15 22:34:19 +08:00
parent 3048471c8b
commit 8c31d98cb5
11 changed files with 227 additions and 26 deletions

View File

@ -11,6 +11,9 @@ module.exports = {
['meta', { name: 'baidu-site-verification', content: '7F55weZDDc'}],
['meta', { name: 'theme-color', content: '#11a8cd'}], // 移动浏览器主题颜色
// 不蒜子访问量统计
// ['script', { src: '//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js', async: 'async'}]
// 以下是vuepress-plugin-demo-block插件所需依赖
// ['script', { src: 'https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js' }], // 此文件会影响导航router-link-active样式的切换
// ['script', { src: 'https://cdn.jsdelivr.net/npm/@babel/standalone/babel.min.js' }],
@ -21,6 +24,10 @@ module.exports = {
themeConfig: { // 主题配置
nav,
sidebar, // 侧边栏 'auto' | 自定义
author: { // 文章默认的作者信息(此项非官方配置,是新增的一项配置)可在md文件中另外指定此项配置
name: 'Evan xu', // 必需
href: 'https://github.com/xugaoyi' // 非必需
},
sidebarDepth: 2, // 侧边栏显示深度默认1最大2显示到h3标题
logo: '/img/EB-logo.png', // 导航栏logo
repo: 'xugaoyi/vuepress-theme-vdoing-blog', // 导航栏右侧生成Github链接

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,5 @@
//
@import '//at.alicdn.com/t/font_1678482_m18ipwgi2da.css'
//
body

View File

@ -0,0 +1,131 @@
<template>
<div class="articleInfo-wrap">
<div class="articleInfo">
<ul class="breadcrumbs">
<li>
<router-link to="/" class="iconfont icon-ai-home icon-home" />
</li>
<li v-if="articleInfo.classify1">
<router-link v-if="articleInfo.cataloguePermalink" :to="articleInfo.cataloguePermalink">{{articleInfo.classify1}}</router-link>
<span v-else>{{articleInfo.classify1}}</span>
</li>
<li v-if="articleInfo.classify2">
<span>{{articleInfo.classify2}}</span>
</li>
</ul>
<div class="info">
<div class="author iconfont icon-touxiang" v-if="articleInfo.author">
<a :href="articleInfo.author.href" v-if="articleInfo.author.href" target="_blank" title="作者">{{articleInfo.author.name}}</a>
</div>
<div class="date iconfont icon-ic_calendar" v-if="articleInfo.date">
<a href="javascript:;" title="创建时间">{{articleInfo.date}}</a>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
articleInfo: {}
}
},
mounted() {
this.articleInfo = this.getPageInfo()
},
watch: {
$route: {
handler:function(){
this.articleInfo = this.getPageInfo()
}
}
},
methods: {
getPageInfo() {
const pageInfo = this.$page
const { relativePath } = pageInfo
const { catalogue } = this.$themeConfig.sidebar
const relativePathArr = relativePath.split('/')
const classifyArr = relativePathArr[0].split('.')
const classify1 = classifyArr.length > 1 ? classifyArr[1] : classifyArr[0] //
const classify2 = relativePathArr.length > 2 ? relativePathArr[1].split('.')[1] : undefined//
const cataloguePermalink = catalogue ? catalogue[classify1] : undefined//
const author = this.$frontmatter.author || this.$themeConfig.author //
let date = pageInfo.frontmatter.date || pageInfo.lastUpdated //
date = Date.parse(date) ? dateFormat(new Date(date)) : undefined
return {
date,
classify1,
classify2,
cataloguePermalink,
author
}
}
}
}
//
function dateFormat(date) {
if (!(date instanceof Date)) {
date = new Date(date)
}
return `${date.getFullYear()}-${zero(date.getMonth()+1)}-${zero(date.getDate())}`
}
// 100
function zero(d){
return d.toString().padStart(2,'0')
}
</script>
<style lang='stylus' scoped>
.articleInfo-wrap
margin-bottom -3.6rem
padding-bottom 0
color gray
.articleInfo
overflow hidden
.breadcrumbs
margin 0
padding 0
overflow hidden
display inline-block
@media (max-width: 960px)
width 100%
li
list-style-type none
float left
padding-right 5px
&:after
content '→'
margin-left: 5px;
&:last-child
&:after
content ''
.icon-home
color gray
text-decoration none
&:hover
color $accentColor
.info
float right
line-height 32px
@media (max-width: 960px)
float left
div
float left
margin-left 20px
font-size .9rem
@media (max-width: 960px)
margin 0 20px 0 0
&:before
margin-right 3px
a
color gray
&.date
a
text-decoration none
</style>

View File

@ -106,7 +106,9 @@
</aside>
</div>
<div class="footer" v-if="data.footer">Copyright © {{ data.footer.year }}-{{ new Date().getFullYear() }} {{ data.footer.content }}</div>
<div class="footer" v-if="data.footer">
Copyright © {{ data.footer.year }}-{{ new Date().getFullYear() }} {{ data.footer.content }}
</div>
</div>
</template>
@ -218,8 +220,6 @@ export default {
</script>
<style lang="stylus">
// @import '//at.alicdn.com/t/font_1678482_k8ld4et1y2f.css'
.slide-banner
margin-top: 2rem;
.banner-wrapper
@ -438,7 +438,9 @@ body .main-wrapper{
.image_title {
width: 11rem;
height: 11rem;
transition: all .3s;
// transition: all .3s;
animation: heart 1.2s ease-in-out 0s infinite alternate;
animation-play-state: paused
}
h2 {
@ -447,20 +449,34 @@ body .main-wrapper{
border-bottom: none;
padding-bottom: 0;
color: lighten($textColor, 10%);
transition: all 1.2s;
}
p {
color: lighten($textColor, 25%);
transition: all 1.2s;
}
}
.feature:hover {
.image_title {
transform:scale(1.1,1.1)
// transform:scale(1.1,1.1);
animation-play-state: running;
}
h2{
color: lighten($textColor, 80%);
}
p{
color: lighten($textColor, 25%);
}
}
}
@keyframes heart{
from{transform:translate(0,0)}
to{transform:translate(0,8px)}
}
.footer {
padding: 2.5rem;
margin-bottom 2rem;

View File

@ -1,8 +1,10 @@
<template>
<main class="page">
<slot name="top" />
<ArticleInfo class="theme-default-content" v-if="isArticle()" />
<component v-if="pageComponent" :is="pageComponent" />
<component class="theme-default-content" v-if="pageComponent" :is="pageComponent" />
<Content class="theme-default-content" />
<PageEdit />
@ -18,17 +20,23 @@
<script>
import PageEdit from '@theme/components/PageEdit.vue'
import PageNav from '@theme/components/PageNav.vue'
import ArticleInfo from './ArticleInfo.vue'
import Catalogue from './Catalogue.vue'
import Article from './Article.vue'
import Timeline from './Timeline.vue'
export default {
components: { PageEdit, PageNav, Catalogue, Article, Timeline},
components: { PageEdit, PageNav, ArticleInfo, Catalogue, Article, Timeline},
props: ['sidebarItems'],
computed: {
pageComponent () {
return this.$frontmatter.pageComponent ? this.$frontmatter.pageComponent.name : false
}
},
methods: {
isArticle() {
return this.$frontmatter.article !== false
}
}
}
</script>

View File

@ -0,0 +1,16 @@
---
pageComponent:
name: Catalogue
data:
key: 04.更多
imgUrl: /img/other.png
description: 学习、面试、在线工具等更多文章和页面
title: 更多
date: 2020-03-11 21:50:56
permalink: /more
sidebar: false
article: false
comment: false
editLink: false
---

View File

@ -2,6 +2,9 @@
title: new命令原理
date: 2019-12-25 14:27:01
permalink: /pages/8143cc480faf9a11
author:
name: '阮一峰'
href: 'https://github.com/xugaoyi'
---
# new命令原理

View File

@ -1,6 +1,6 @@
---
title: 关于
date: 2019-12-25 14:27:01
date: 2019-12-25 14:27:01
permalink: /about
sidebar: false
article: false

View File

@ -18,7 +18,7 @@ features:
imgname: /img/other.png
aside:
avatar: https://cdn.jsdelivr.net/gh/xugaoyi/image_store/blog/20200103123203.jpg
iconfontCssFile: //at.alicdn.com/t/font_1678482_u4nrnp8xp6g.css # 阿里矢量图标库在线css文件地址
# iconfontCssFile: //at.alicdn.com/t/font_1678482_u4nrnp8xp6g.css # 阿里图标库在线css文件地址,对于原本没有的图标可以另外添加
icons:
# - iconClass: icon-QQ
# title: QQ
@ -33,7 +33,7 @@ aside:
title: 听音乐
link: https://music.163.com/#/playlist?id=755597173
blogger:
name: Evan Xu
name: Evan xu
slogan: 前端界的小学生
footer:
year: 2019

View File

@ -10,15 +10,21 @@ const matter = require('gray-matter'); // FrontMatter解析器
const docsRoot = path.join(__dirname, '..', 'docs'); // docs文件路径
const sidebarPath = path.join(__dirname, '..', 'docs', '.vuepress', 'config', 'sidebar-auto.js'); // 侧边栏js文件要保存的路径
const catalogueData = {}; // 目录页数据
// sidebar-auto.js代码模板
const sidebarTemplate = `
// 侧边栏自动生成 // 最里面的数组,格式:[<path>, <title>, <permalink>]其中permalink并非侧边栏所需而是提供给其他页面使用
/**
* 自动生成的侧边栏
* 说明
* 1. 最里边的数组格式[<path>, <title>, <permalink>]其中permalink并非侧边栏所需而是提供给其他页面目录页使用
* 2. catalogue属性是提供给面包屑所需的目录页数据
*/
module.exports = {
<% for (let item of sidebarData) { %>
"<%- item.path %>": <%- JSON.stringify(item.sidebarArr) %>,
"<%- item.path %>": <%- JSON.stringify(item.sidebarArr) %>,
<% } %>
"catalogue": <%- JSON.stringify(catalogueData) %>
}`;
main();
@ -43,7 +49,7 @@ function main() {
})
})
const sidebarDataTem = ejs.render(sidebarTemplate, { sidebarData });
const sidebarDataTem = ejs.render(sidebarTemplate, { sidebarData, catalogueData });
fs.writeFileSync(sidebarPath, sidebarDataTem); // 同步写入文件, 参数一:写入到的文件, 参数二:写入的数据
logger.info('侧边栏生成成功!')
}
@ -103,6 +109,12 @@ function mapTocToSidebar(root, prefix){
const { data } = matter(contentStr) // 解析出front matter数据
const permalink = data.permalink || ''
sidebar[order] = [prefix + filename, title, permalink ]; // [<路径>, <文件标题>, <永久链接>]
// 目录页和永久链接,用于给面包屑提供数据
const pageComponent = data.pageComponent
if (pageComponent && pageComponent.name && pageComponent.name === "Catalogue") {
catalogueData[title] = permalink
}
}
})