新增分类栏和标签栏

This commit is contained in:
xugaoyi 2020-04-29 16:53:17 +08:00
parent e73c24d60c
commit 24d26c1d47
20 changed files with 471 additions and 676 deletions

View File

@ -113,38 +113,19 @@ npm run dev # or yarn dev
[vuepress-plugin-one-click-copy](https://www.npmjs.com/package/vuepress-plugin-one-click-copy)
3. H1标题美化徽章插件
[title-badge](https://github.com/xugaoyi/vuepress-theme-vdoing/tree/master/docs/.vuepress/plugins/title-badge)
> 此插件未上传npm以本地插件引入:
```js
// config.js
module.exports = {
plugins: [
[require('./plugins/title-badge'), { // h1标题徽章
// badges: [ // 替换默认的徽章图标
// 'data:image/png;base64,**',
// 'data:image/png;base64,***',
// ]
}]
]
}
```
4. 可以添加第三方搜索链接的搜索框插件
3. 可以添加第三方搜索链接的搜索框插件
[vuepress-plugin-thirdparty-search](https://github.com/xugaoyi/vuepress-plugin-thirdparty-search)
5. 百度推送和统计插件
4. 百度推送和统计插件
[vuepress-plugin-baidu-autopush](https://www.npmjs.com/package/vuepress-plugin-baidu-autopush)
[vuepress-plugin-baidu-tongji](https://www.npmjs.com/package/vuepress-plugin-baidu-tongji)
6. 更多插件查看官方[Awesome VuePress](https://github.com/vuepressjs/awesome-vuepress)
5. 更多插件查看官方[Awesome VuePress](https://github.com/vuepressjs/awesome-vuepress)
## 部署

View File

@ -42,6 +42,12 @@ module.exports = {
// length: 3, // 显示的数量默认3
// moreArticle: '/timeline' // “更多文章”跳转的页面,默认'/timeline'
// },
// titleBadge: false, // 文章标题前的图标是否显示默认true
// titleBadgeIcons: [ // 文章标题前图标的链接,默认主题内置图标
// '图标链接1',
// '图标链接2'
// ],
author: { // 文章默认的作者信息可在md文件中单独配置此信息 String | {name: String, href: String}
name: 'Evan Xu', // 必需
href: 'https://github.com/xugaoyi' // 可选的
@ -82,12 +88,12 @@ module.exports = {
// color: '#11a8cd', // 爱心颜色,默认随机色
// excludeClassName: 'theme-vdoing-content' // 要排除元素的class, 默认空''
// }],
[require('./plugins/title-badge'), { // h1标题徽章
// badges: [ // 替换默认的徽章图标,可选
// 'base64图片1',
// 'base64图片2',
// ]
}],
// [require('./plugins/title-badge'), { // h1标题徽章
// // badges: [ // 替换默认的徽章图标,可选
// // 'base64图片1',
// // 'base64图片2',
// // ]
// }],
['thirdparty-search', { // 可以添加第三方搜索链接的搜索框(原官方搜索框的参数仍可用)
thirdparty: [ // 可选,默认 []

View File

@ -1,10 +1,4 @@
// h1
h1
img
width 1.6rem
//
.gt-container
.gt-ico-tip

View File

@ -4,6 +4,7 @@ date: 2020-04-24 14:30:27
permalink: /pages/2868d3
categories:
- 博文
- 测试
tags:
- test
- 博客

View File

@ -1,13 +1,13 @@
<template>
<div class="articleInfo-wrap">
<div class="articleInfo">
<ul class="breadcrumbs">
<ul class="breadcrumbs" v-if="articleInfo.classify1 && articleInfo.classify1 !== '_posts'">
<li>
<router-link to="/" class="iconfont icon-home" title="首页" />
</li>
<li v-if="articleInfo.classify1">
<li>
<router-link v-if="articleInfo.cataloguePermalink" :to="articleInfo.cataloguePermalink" :title="articleInfo.classify1+'-目录页'">{{articleInfo.classify1}}</router-link>
<span v-else>{{articleInfo.classify1 === '_posts' ? '博客文章' : articleInfo.classify1 }}</span>
<span v-else>{{ articleInfo.classify1 }}</span>
</li>
<li v-if="articleInfo.classify2">
<router-link v-if="articleInfo.cataloguePermalink" :to="articleInfo.cataloguePermalink + '/#' + encodeAnchor(articleInfo.classify2)" :title="articleInfo.classify1+'#'+articleInfo.classify2">{{articleInfo.classify2}}</router-link>
@ -15,12 +15,17 @@
</li>
</ul>
<div class="info">
<div class="author iconfont icon-touxiang" v-if="articleInfo.author">
<div class="author iconfont icon-touxiang" title="作者" v-if="articleInfo.author">
<a :href="articleInfo.author.href" v-if="articleInfo.author.href" target="_blank" class="beLink" title="作者">{{articleInfo.author.name}}</a>
<a v-else href="javascript:;" title="作者">{{articleInfo.author.name || articleInfo.author}}</a>
<a v-else href="javascript:;">{{articleInfo.author.name || articleInfo.author}}</a>
</div>
<div class="date iconfont icon-riqi" v-if="articleInfo.date">
<a href="javascript:;" title="创建时间">{{articleInfo.date}}</a>
<div class="date iconfont icon-riqi" title="创建时间" v-if="articleInfo.date">
<a href="javascript:;" >{{articleInfo.date}}</a>
</div>
<div class="date iconfont icon-wenjian" title="分类" v-if="!(articleInfo.classify1 && articleInfo.classify1 !== '_posts') && articleInfo.categories">
<a href="javascript:;" v-for="(item, index) in articleInfo.categories" :key="index">
{{item}}
</a>
</div>
</div>
</div>
@ -29,7 +34,6 @@
<script>
import encodeMixin from '../mixins/encodeAnchor'
import { dateFormat } from '../util'
export default {
mixins: [encodeMixin],
@ -42,10 +46,8 @@ export default {
this.articleInfo = this.getPageInfo()
},
watch: {
$route: {
handler:function(){
this.articleInfo = this.getPageInfo()
}
'$route.path'() {
this.articleInfo = this.getPageInfo()
}
},
methods: {
@ -53,20 +55,27 @@ export default {
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
let date = (pageInfo.frontmatter.date || '').split(' ')[0] //
// frontmatter使
const { categories } = this.$frontmatter
return {
date,
classify1,
classify2,
cataloguePermalink,
author
author,
categories
}
}
}

View File

@ -0,0 +1,76 @@
<template>
<aside class="blogger-wrapper card-box">
<div class="avatar">
<img :src="blogger.avatar" alt="头像" title="我好看吗">
</div>
<div class="icons" v-if="social">
<a
v-for="(item, index) in social.icons"
:key="index"
:href="item.link"
:title="item.title"
:class="['iconfont', item.iconClass]"
:style="{width: 100/social.icons.length + '%'}"
target="_blank"
/>
</div>
<div class="blogger">
<span class="name">
{{blogger.name}}
</span>
<span class="slogan">
{{blogger.slogan}}
</span>
</div>
</aside>
</template>
<script>
export default {
computed: {
blogger() {
return this.$themeConfig.blogger
},
social() {
return this.$themeConfig.social
}
}
}
</script>
<style lang='stylus'>
.blogger-wrapper
height auto
display inline-table
.avatar
width 245px
height 245px
overflow hidden
img
width 100%
height 100%
border-radius 3px
.icons
border 1px solid var(--borderColor)
border-top none
height 40px
line-height 40px
a
font-size 20px
width 33%
color var(--textColor)
display block
float left
text-align center
opacity .8
&:hover
color $accentColor
.blogger
margin 15px 0 10px 0
.name
font-size 1.4rem
display: block
margin-bottom 6px
.slogan
color var(--textColor)
</style>

View File

@ -3,20 +3,20 @@
<transition name="fade">
<div
title="返回顶部"
class="button go-to-top iconfont icon-fanhuidingbu"
class="button blur go-to-top iconfont icon-fanhuidingbu"
v-show="showToTop"
@click="scrollToTop"
/>
</transition>
<div
title="去评论"
class="button go-to-comment iconfont icon-pinglun"
class="button blur go-to-comment iconfont icon-pinglun"
v-show="showCommentBut"
@click="scrollToComment"
/>
<div
title="主题模式"
class="button theme-mode-but iconfont icon-zhuti"
class="button blur theme-mode-but iconfont icon-zhuti"
@mouseenter="showModeBox = true"
@mouseleave="showModeBox = false"
@click="showModeBox = true"
@ -170,7 +170,7 @@ export default {
}
},
watch: {
$route() {
'$route.path'() {
this.handleShowCommentBut()
this.getCommentTop()
}
@ -200,7 +200,7 @@ export default {
text-align center
cursor pointer
transition all .5s
background var(--bg)
background var(--blurBg)
&:hover
background $accentColor
box-shadow 0 0 15px $accentColor

View File

@ -80,7 +80,7 @@ export default {
}
},
watch: {
$route() {
'$route.path'() {
this.getPageData()
}
}

View File

@ -0,0 +1,48 @@
<template>
<div class="categories-wrapper card-box">
<router-link to="/" class="title iconfont icon-wenjianjia" title="全部分类">
文章分类
</router-link>
<div class="categories">
<router-link to="/" v-for="(item, index) in categories" :key="index">
{{item.key}}
<span>({{item.length}})</span>
</router-link>
<router-link to="/" v-if="$categoriesAndTags.categories.length > 10">
更多...
</router-link>
</div>
</div>
</template>
<script>
export default {
computed: {
categories() {
return this.$categoriesAndTags.categories.slice(0, 10)
}
}
}
</script>
<style lang='stylus'>
.categories-wrapper
.title
color var(--textColor)
opacity .8
font-size 1.2rem
&:hover
color $accentColor
.categories
padding-top .5rem
a
display block
padding .3rem 0
color var(--textColor)
opacity .8
font-size .95rem
&:hover
color $accentColor
span
float right
</style>

View File

@ -61,29 +61,9 @@
</div>
<div class="main-right">
<aside class="blogger-wrapper card-box" v-if="blogger">
<div class="avatar">
<img :src="blogger.avatar" alt="头像" title="我好看吗">
</div>
<div class="icons" v-if="social">
<a
:href="item.link"
:title="item.title"
:class="['iconfont', item.iconClass]"
v-for="(item, index) in social.icons"
:key="index"
:style="{width: 100/social.icons.length + '%'}"
target="_blank"
>
</a>
</div>
<div class="blogger">
<span class="name">{{blogger.name}}</span>
<span class="slogan">
{{blogger.slogan}}
</span>
</div>
</aside>
<BloggerBar v-if="$themeConfig.blogger" />
<CategoriesBar />
<TagsBar />
</div>
</div>
@ -96,6 +76,9 @@ import NavLink from "@theme/components/NavLink";
import BScroll from "@better-scroll/core"
import Slide from "@better-scroll/slide"
import PostList from '@theme/components/PostList'
import BloggerBar from '@theme/components/BloggerBar'
import CategoriesBar from '@theme/components/CategoriesBar'
import TagsBar from '@theme/components/TagsBar'
import Footer from '@theme/components/Footer'
const MOBILE_DESKTOP_BREAKPOINT = 720 // refer to config.styl
@ -109,15 +92,10 @@ export default {
slide: null,
currentPageIndex: 0,
playTimer: 0,
mark: 0,
updateBarConfig: null,
social: null
mark: 0
}
},
created() {
this.updateBarConfig = this.$themeConfig.updateBar
this.social = this.$themeConfig.social
},
components: { NavLink, PostList, BloggerBar, CategoriesBar, TagsBar, Footer },
beforeMount(){
this.isMQMobile = window.innerWidth < MOBILE_DESKTOP_BREAKPOINT ? true : false; // vupressbeforeCreate(),created()访apiwindow
@ -131,15 +109,6 @@ export default {
}
})
//
if(this.social && this.social.iconfontCssFile ) {
let linkElm = document.createElement("link")
linkElm.setAttribute('rel', 'stylesheet');
linkElm.setAttribute("type", "text/css")
linkElm.setAttribute("href", this.social.iconfontCssFile)
document.head.appendChild(linkElm)
}
},
mounted() {
this.isMQMobile && this.init()
@ -187,8 +156,6 @@ export default {
}
},
components: { NavLink, PostList, Footer },
computed: {
homeData() {
return {
@ -196,12 +163,6 @@ export default {
base: this.$site.base
}
},
isShowUpdateBar() {
return this.updateBarConfig && this.updateBarConfig.onHome && this.updateBarConfig.onHome.isShow === false ? false : true
},
blogger() {
return this.$themeConfig.blogger
},
footerBgImg() {
return this.$themeConfig.footer && this.$themeConfig.footer.footerBgImg
},
@ -360,42 +321,9 @@ export default {
flex 1
.main-right
.card-box
margin-left .9rem
.blogger-wrapper
padding 15px
height auto
display inline-table
.avatar
width 245px
height 245px
overflow hidden
img
width 100%
height 100%
border-radius 3px
.icons
border 1px solid var(--borderColor)
border-top none
height 40px
line-height 40px
a
font-size 20px
width 33%
color var(--textColor)
display block
float left
text-align center
opacity .8
&:hover
color $accentColor
.blogger
margin 15px 0 10px 0
.name
font-size 1.4rem
display: block
margin-bottom 6px
.slogan
color var(--textColor)
margin 0 0 .9rem .9rem
padding .95rem
.footer
background none

View File

@ -1,473 +0,0 @@
<template>
<div class="i-body" :style="footerBgImg && `background-image: url(${footerBgImg})`">
<div class="banner" :style="data.bgImg && `background: url(${$withBase(data.bgImg)}) center center / cover no-repeat`">
<main class="home" :style="!data.features && `padding-top: 7rem`">
<header class="hero">
<img v-if="data.heroImage" :src="$withBase(data.heroImage)" :alt="data.heroAlt || 'hero'" />
<h1 v-if="data.heroText !== null" id="main-title">{{ data.heroText || $title || 'Hello' }}</h1>
<p class="description">{{ data.tagline || $description || 'Welcome to your VuePress site' }}</p>
<p class="action" v-if="data.actionText && data.actionLink">
<NavLink class="action-button" :item="actionLink" />
</p>
</header>
<!-- PC端features块 s -->
<div class="features" v-if="data.features && data.features.length && !isMQMobile">
<div class="feature" v-for="(feature, index) in data.features" :key="index">
<router-link :to="feature.link">
<img class="image_title" :src="$withBase(feature.imgUrl)" :alt="feature.title" />
<h2>{{ feature.title }}</h2>
<p>{{ feature.details }}</p>
</router-link>
</div>
</div>
<!-- PC端features块 e -->
</main>
<!-- 移动端slide s -->
<div class="slide-banner" v-if="data.features && data.features.length" v-show="isMQMobile">
<div class="banner-wrapper">
<div class="slide-banner-scroll" ref="slide">
<div class="slide-banner-wrapper">
<div class="slide-item" v-for="(feature, index) in data.features" :key="index">
<router-link :to="feature.link">
<img class="image_title" :src="$withBase(feature.imgUrl)" :alt="feature.title" />
<h2>{{ feature.title }}</h2>
<p>{{ feature.details }}</p>
</router-link>
</div>
</div>
</div>
<div class="docs-wrapper">
<span
class="doc"
v-for="(item, index) in data.features.length"
:key="index"
:class="{'active': currentPageIndex === index}"></span>
</div>
</div>
</div>
<!-- 移动端slide e -->
</div>
<div class="main-wrapper">
<main class="home home-content" aria-labelledby="main-title">
<UpdateArticle
pageMark="home"
:length="updateBarConfig && updateBarConfig.onHome && updateBarConfig.onHome.length || 5"
:moreArticle="updateBarConfig && updateBarConfig.moreArticle"
v-if="isShowUpdateBar"
/>
<Content class="theme-vdoing-content custom" />
</main>
<aside class="info-wrapper" v-if="blogger">
<div class="avatar">
<img :src="blogger.avatar" alt="头像">
</div>
<div class="icons" v-if="social">
<a
v-for="(item, index) in social.icons"
:key="index"
:href="item.link"
:title="item.title"
:class="['iconfont', item.iconClass]"
:style="{width: 100/social.icons.length + '%'}"
target="_blank"
>
</a>
</div>
<div class="blogger">
<span class="name">{{blogger.name}}</span>
<span class="slogan">
{{blogger.slogan}}
</span>
</div>
</aside>
</div>
<Footer />
</div>
</template>
<script>
import NavLink from "@theme/components/NavLink.vue";
import BScroll from "@better-scroll/core"
import Slide from "@better-scroll/slide"
import UpdateArticle from './UpdateArticle.vue'
import Footer from './Footer.vue'
const MOBILE_DESKTOP_BREAKPOINT = 720 // refer to config.styl
BScroll.use(Slide)
export default {
data(){
return {
isMQMobile: false,
slide: null,
currentPageIndex: 0,
playTimer: 0,
mark: 0,
updateBarConfig: null,
social: null
}
},
created() {
this.updateBarConfig = this.$themeConfig.updateBar
this.social = this.$themeConfig.social
// console.log(this)
},
beforeMount(){
this.isMQMobile = window.innerWidth < MOBILE_DESKTOP_BREAKPOINT ? true : false; // vupressbeforeCreate(),created()访apiwindow
window.addEventListener('resize', () => {
this.isMQMobile = window.innerWidth < MOBILE_DESKTOP_BREAKPOINT ? true : false;
if(this.isMQMobile && !this.slide && !this.mark){
this.mark++
setTimeout(() => {
this.init()
},60)
}
})
//
if(this.social && this.social.iconfontCssFile ) {
let linkElm = document.createElement("link")
linkElm.setAttribute('rel', 'stylesheet');
linkElm.setAttribute("type", "text/css")
linkElm.setAttribute("href", this.social.iconfontCssFile)
document.head.appendChild(linkElm)
}
},
mounted() {
this.isMQMobile && this.init()
},
beforeDestroy() {
clearTimeout(this.playTimer)
this.slide && this.slide.destroy()
},
methods: {
init() {
clearTimeout(this.playTimer)
this.slide = new BScroll(this.$refs.slide, {
scrollX: true, // x
scrollY: false, // y
slide: {
loop: true,
threshold: 100
},
useTransition: true, // 使css3 transition
momentum: false,
bounce: false, //
stopPropagation: false, //
probeType: 2,
preventDefault: false
})
// user touches the slide area
this.slide.on('beforeScrollStart', () => {
clearTimeout(this.playTimer)
})
// user touched the slide done
this.slide.on('scrollEnd', () => {
this.autoGoNext()
})
this.slide.on('slideWillChange', (page) => {
this.currentPageIndex = page.pageX
})
this.autoGoNext()
},
autoGoNext() {
clearTimeout(this.playTimer)
this.playTimer = setTimeout(() => {
this.slide.next()
}, 4000)
}
},
components: { NavLink, UpdateArticle, Footer },
computed: {
data() {
return this.$page.frontmatter;
},
isShowUpdateBar() {
return this.updateBarConfig && this.updateBarConfig.onHome && this.updateBarConfig.onHome.isShow === false ? false : true
},
blogger() {
return this.$themeConfig.blogger
},
footerBgImg() {
return this.$themeConfig.footer && this.$themeConfig.footer.footerBgImg
},
actionLink() {
return {
link: this.data.actionLink,
text: this.data.actionText
};
}
}
};
</script>
<style lang="stylus">
//
.slide-banner
margin-top: 2rem;
.banner-wrapper
position relative
.slide-banner-scroll
min-height 1px
overflow hidden
.slide-banner-wrapper
height 300px
.slide-item
display inline-block
height 300px
width 100%
text-align center
.image_title
width: 10rem;
height: 10rem;
h2
font-size: 1.1rem;
color: #fff;
font-weight: 500;
border-bottom: none;
padding-bottom: 0;
p
color: #b0b6be;
.docs-wrapper
position absolute
bottom 25px
left 50%
transform translateX(-50%)
.doc
display inline-block
margin 0 4px
width 8px
height 8px
border-radius 50%
background #2F455A
&.active
background #517EA9
.i-body
background bottom no-repeat
background-color var(--pageBg)
overflow hidden
.footer
background none
.banner
width 100%
min-height 450px
background rgb(40,40,45)
color #fff
position relative
overflow hidden
background-image url(../images/bg-line.png)
background-size 35px 35px
.home
background none
position relative
z-index 1
.hero
h1
font-size 3.5rem
margin: 3.5rem auto 1.8rem auto
.description
font-size 1.2rem
color #fff
.features
border-top none
.feature
h2
font-size 1.3rem
color #fff
p
color #fff
opacity 0.8
// color #B0B6BE
body .main-wrapper
margin 2rem auto
max-width 1080px
position relative
display flex
>*
border-radius 5px
background var(--bg)
box-shadow 0 1px 2px 0 rgba(0,0,30,.1), 0 2px 4px 0 rgba(0,0,0,.1)
.home-content
padding 1rem 1.5rem 0
flex 1
.info-wrapper
width 260px
padding 15px
height auto
margin-left 10px
display inline-table
.avatar
width 260px
height 260px
overflow hidden
img
width 100%
height 100%
border-radius 3px
.icons
border 1px solid var(--borderColor)
height 40px
line-height 40px
a
font-size 20px
width 33%
color var(--textColor)
display block
float left
text-align center
opacity .8
&:hover
color $accentColor
.blogger
margin 15px 0 10px 0
.name
font-size 24px
display: block
margin-bottom 10px
.slogan
color var(--textColor)
.home
padding $navbarHeight 2rem 0
max-width 1080px
margin 0px auto
display block
.hero
text-align center
img
max-width 100%
max-height 192px
display block
margin 2rem auto 1.5rem
h1
font-size 3rem
h1, .description, .action
margin 1.8rem auto
.description
max-width 40rem
font-size 1.4rem
line-height 1.3
color var(--textLightenColor)
.action-button
display inline-block
font-size 1.2rem
color #fff
background-color $accentColor
padding 0.8rem 1.6rem
border-radius 4px
transition background-color 0.1s ease
box-sizing border-box
border-bottom 1px solid darken($accentColor, 10%)
&:hover
background-color lighten($accentColor, 10%)
.features
border-top 1px solid var(--borderColor)
padding 2rem 0
margin-top 2.5rem
display flex
flex-wrap wrap
align-items flex-start
align-content stretch
justify-content space-between
.feature
flex-grow 1
flex-basis 30%
max-width 30%
text-align center
.image_title
width 11rem
height 11rem
animation heart 1.2s ease-in-out 0s infinite alternate
animation-play-state paused
h2
font-weight 500
border-bottom none
padding-bottom 0
.feature:hover
.image_title
animation-play-state: running
h2,p
opacity .7
// color var(--textLightenColor)
@keyframes heart
from{transform:translate(0,0)}
to{transform:translate(0,8px)}
@media (max-width: 1025px)
.i-body
background-color var(--bg)
body .home-content
margin 0
border-radius 0
body .main-wrapper >*
box-shadow none
.banner .home
.hero h1
font-size 2.5rem
.feature h2
font-size 1.1rem
.hero .description
font-size 1rem
.home .feature .image_title
width 10rem
height 10rem
@media (max-width: 765px)
body .main-wrapper .info-wrapper
width 200px
.avatar
width: 200px
height: 200px
@media (max-width: $MQMobile)
body .main-wrapper
margin 0
display block
.info-wrapper
display none
.home-content
padding-top 1.5rem
// 719px
.banner
// min-height 517px
.home .hero h1
// margin 1.8rem auto
.home
.features
display none
flex-direction column
margin-top 0
.feature
max-width 100%
padding 0 2.5rem
margin 0 auto
@media (max-width: $MQMobileNarrow)
// 419px
.home
padding-left 1.5rem
padding-right 1.5rem
.hero
img
max-height 210px
margin 2rem auto 1.2rem
h1
font-size: 2rem
h1, .description, .action
margin: 1.2rem auto
.description
font-size: 1.2rem
.action-button
font-size 1rem
padding 0.6rem 1.2rem
.feature
h2
font-size: 1.25rem
</style>

View File

@ -1,5 +1,5 @@
<template>
<header class="navbar">
<header class="navbar blur">
<SidebarButton @toggle-sidebar="$emit('toggle-sidebar')"/>
<router-link

View File

@ -10,8 +10,11 @@
<div class="content-wrapper">
<RightMenu v-if="showRightMenu"/>
<h1>{{this.$page.title}}</h1>
<Content class="theme-vdoing-content" ref="vdoingContent" />
<h1 v-if="showTitle">
<img :src="currentBadge" v-if="$themeConfig.titleBadge === false ? false : true">
{{this.$page.title}}
</h1>
<Content class="theme-vdoing-content" />
</div>
@ -45,21 +48,38 @@ import RightMenu from './RightMenu.vue'
export default {
data() {
return {
updateBarConfig: null
updateBarConfig: null,
badges: [
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAABGpJREFUSA3tVVtoXFUU3fvOI53UlmCaKIFmwEhsE7QK0ipFEdHEKpXaZGrp15SINsXUWvBDpBgQRKi0+KKoFeJHfZA+ED9KKoIU2gYD9UejTW4rVIzm0VSTziPzuNu1z507dibTTjL4U/DAzLn3nL3X2o91ziX6f9wMFdh6Jvbm9nNSV0msViVO6tN1Rm7NMu2OpeJ9lWBUTDxrJbYTS0hInuwciu9eLHlFxCLCZEk3MegsJmZ5K/JD6t7FkFdEvGUo1g7qJoG3MHImqRIn8/nzY1K9UPKKiJmtnUqHVE3Gbuay6vJE/N2FEmuxFjW2nUuE0yQXRRxLiTUAzs36zhZvOXJPdX850EVnnLZkB8prodQoM5JGj7Xk2mvC7JB8tG04Ef5PiXtG0UtxupRQSfTnBoCy554x18yJHI6I+G5Eru4LHmPJZEQsrvPUbMiA8G/WgMK7w7I+ez7++o2ANfbrjvaOl1tFMs+htG3IrZH9/hDX1Pr8Tc0UvH8tcX29KzAgIGcEkINyW5BF9x891hw6VYqgJHEk0huccS7vh3C6gTiODL+26huuBtbct8eZnqLML8PkxGYpuPZBqtqwkSjgc4mB5gbgig5i+y0UDK35LMxXisn9xQtK+nd26gTIHsHe/oblK/b29fUmN/8Y+9jAQrnBp56m1LcDlDp9irKTExSKduXJVWSqdBMA08pEJnEIOB3FPPMybu/oeV8zFeYN3xx576Q6RH+VmplE4ncQV5v+5rzSoyOU7PuEAg8g803PwBJ0CExno/jcMbN8tONYeOmHiuUNryvm3fRUy4tMPVLdAGkUhNWuggGrJcXPv+ouCjz0MKUHz1J2/E8IC9nqTabcxgaBYM0hPhD5Y65FsbxRQKxCQrDjDctW7PUM3HuZunFyifSAqEfuzCp48Il24luWUWZoyJCaPR82jE0+kFA643wRFVni4RYSq3ohJO2pZ7B5dO4xkDWbEpossJPLSrPjYID8rS2UHTlvyNxqIGsg674XJJ7vnh5L7PNwC4hh2sjCI96mzszOTpxLF0T7l88Yz7lAuK6OnL8gXLOnTvpzSb22YG8W7us3jSebFHeeqnXRG1vt+MoUM84LQIBmMsCTAcOauTh0T0l0neQK7m2bLMt2mGxU3HYssS0J2cdv5wljlPsrIuZLAG/2DOZIXgCYT8uMGZN+e2kSirfxZOPCsC0f24nTZzspnVn9VePS1Z5vubmAGGXG8ZFno9Hel0yfA5ZPhF7Dh972BQJ2qCpgH67lmWtBYbvk6sz02wjky2vXyz0XErP/kFB619js1BtwfOV4OPRqOQBjy3Qbk18vigUPPSD5ceHnwck7W9bhAqZdd7SuG7w4/P2F/GaJh8c7e9qgow+Q7cGBo+98WsLkuktFqiZabtXuQTu/Y5ETbR0v7tNSFnvrmu6pjdoan2KjMu8q/Hmj1EfCO2ZGfEIbIXKUlw8qaX9/b2oeSJmFksSeT/Fn0V3nSypChh4Gjh74ybO9aeZ/AN2dwciu2/MhAAAAAElFTkSuQmCC',
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAABH1JREFUSA3tVl1oHFUUPmdmd2ltklqbpJDiNnXFmgbFktho7YMPNiJSSZM0+CAYSkUELVhM6YuwIPpgoOKDqOBDC0XE2CQoNtQXBUFTTcCi+Wlh1V2TQExsUzcltd3M9Tt3ZjZzZ2fT+OJTL8yeM+eee757fmeJbq//KQL8X3DUSFOcfr7cRsRtxNQMWueeVzOkaITIGqQHNg5y8+jNW9ldM7A6nTpAjuolUikAwq7CE3WcM2RRDz+XGVgN3FptU/aUSlvq9Pa3iZ1+sgAqJyyAFqkipd9dqiwHF3P65YycLWc/6sqGrvoEoIp6DOFaX5h6+dnfjkWprwqsPk0dUGq5vySwDImC10KxFHgGL1SWoc92O3eVht09qdXNH11I2SsTsJYqMWzihqGMi+A+Garf3BAuuLI5oGlULyNfyB/HYNujwktOfRrMr5t77NmevqaUopx0grnKAyvVpmwUDB4x6FPXuGvYLTDwWsejwgtgkYKPqRJg8SV6xaiZ3ZTppGneS4yfH5/66fZSDHv+QZci/+h5c5UHtpy67JUqGppM0sh0Nc1dW6/N1W5Yoqat8/TU/VnadmdeW2PLLSyh0cvxBs3KbqTmwYPpxN4do/mzE8nEpvX/UMu2Wbp74zUAK5q6WkHns7V0eWkdPbPzd3rxkTGybadYySumVzhcaJFbs5UrEkQ/+CK8gF5dnh/6ciIZ73gwQ927L1IitoxKLXYP3SjYdOrHHfTZhRRlFyrorafPk20B3HPD1y2G3qKZME5Jcf3t/HUC13/8tSd++vqFveMUTwAUxSUFI1QekR1+bIze3D9MF2aq6cPvG72CgnldWCFqyRw3lwH8ZMerjTD9ElRO7Gv44wNpC90aASqGfVlz/Rx17srQ57/UU26hkhQqUB7dBR71WmzQhHUnblGmVOEw0jhbV1n9OlXUDCIRGaNV5Jp43N516fN7JmnTHdfp7Hgy0luO4aMhtkLL8Bi3bUWYvzh5Mn1dTxrL6QmGuRhGL/TiTTxRoEdTszSaq9GR0NGA3KdkOz3hqSV3MIDhQ5IVX/Ivx3umBti2es2h4eZby7x8br1rkf7Mo90AqC8aQ3sJeNzqFRu+vSANAQe3PL7l0HGOAdwDCeZYvNKeoZp1Qfs6Aipndh86HmFRi0LAnEO47wsqM6cdfjh3jBPUzhZy7nvlUfFsamED1VQt6aISHVymXZ/B2aCtIG8AI8xfobj2d3en1wWVhOeHELKmLQ1s211s88comkv4UCwWyF787mJdYXtNfhKAXVqnKTq8QZvGAGGOfaTo5pGZ/PwbUCr5+DPr/1J92JNHr9aOl/F3iI5+O1nfybsGxoimvZ3ViWSluDITw3P37mypheDIPY0tw7+O/5ApbkYw+zpfaUVu32Pi98+defdUhEpZkRFq0aqyNh9FuL9hpYbEm6iwi0z2REd09ZmyENEbuhjDWzKvZXTqKYaBIr3tt5kuPtQBZFvEUwHt60vfCNu41XsksH9Ij1BMMz1Y0OOunHNShFIP5868g5zeXmuLwL9T4b6Q2+KejgAAAABJRU5ErkJggg==',
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAABKFJREFUSA3tVl1oFVcQnrMbrak3QUgkya1akpJYcrUtIqW1JvFBE9LiQ5v6JmJpolbMg32rVrhgoYK0QiMY6i9Y6EMaW5D+xFJaTYItIuK2Kr3+BJNwkxBj05sQY3b3nM6cs2dv9t7NT/vQJw/sndk5M/PNzJkzewGerP+pAmy+ON8lLzUJgA8ZYxYIYZmGYRnctDaWvJJAmTtfP1pvXsBCCPP8QFcCaRkZYACgDZFO4stNIcBCajEOlmmC9XpJ9bAGCaPaPmzPl32dvLSVu3BWCTQs0XQQ6g0DYgwLIoAZbBCdW/i+781o1VVlm/410mw4h06Y7bIPHNyWDyL4FHkX03Q8SrzNhZTZriieckWt7cL6MM85YcLpsi/7O9/iXFT6MswI0DmmpkSaJ0qLxFIm3+i1THHB3zmBH3PYx9CcykcLOeQVVa7QtdxTgQgEleX2AjHYfwA+2ddV77ruGoJUbhGDI09YSNXyMpUt5ylOzxgbUmtOp7NmbNt8v3arjTBfYELmLUV+M+nSawNNAUqpT3ClJWg5I3BLT+cGW/DXNGCa6tx1aakCGEigArTn4TDIPdrXXYKCZNrHLMCOEPvHBlLQ99s9eHB7EB6NTki73CVPQ2F5MSx/uRQixfmq7rK0wYD8w8E905bnPDfwoWs/rfv93NWN/ZfvwsLIU7A09gxECyISeGJkHAau98L97tuw7NXnoPyNF8FcYGLGKsOs0mN3OEyec9esGW/ZEl945dTP34wlR2FZVQWU1q0Cw8Tr7p+hgLLNL0FPxx/Q35mA8aEUrH6nCgwEl0tn7wUiZYJnNRh6DK4UH/k0lfyrsBKdPVv/AriGIQcEDQZ65LBAGe2Rzui9Ybjz7XUppz1/uKBbyVPGkN3ZAeC6hr0x7Nr38N5+EqkoOm17xpoqR9ohQF55ERSvr4Dkr3chNfC3DMzGJlNBElW8w9nsGQvhNGIzDkXzCg8cLK951xHsFBlTJspJNi3ZFIMF2AeDV3q8DNOB+YHi6QTrChDIWDBRi5U5f+ZMfJLu3ccrqxtdxk4SKH336LFxSmkqefwU5T8fhdSdQf9IVKD6aNiwI/hnmcAZ91isYMJIaCUCx9W098+LgruikeTqzqqxKPUwqJyCPJiyemVVZBOijDGjD38Os0jOiSPL1z3SPjXNANbiNPXAdzTfukjjuknNBbyz3nwgTd3AVFqUJ5hpHlq9MveLnWwttUfoygBmvVjuikxND3znrhsELnZk7k+OjIGxeNEkomyLVta0xxn+HZhjBc4YZ/AFjHjz9u3xRZl2BN4aq9nFwWh16IrQ1aHHEd3j1+4/dB9OtH4e29A2H1DyHQRmOSfQZ1Fy7MHBTGB6J/Djq6p3OxyO2cB+4Car7v/o3GXgfAkj23+x9ID1Teoamo/SXcbvSf2PX7Vc8DdCmE1vN9di+32P9/5YR3vLnhCVGUWBjEkr3yh4H8v9CzmsbdhzOKzsJKM90iFdaTMjRPhGVsakRvOaRidljo6H6G7j+ctrJpsP+4COhDIl0La2+FS4+5mlocBaXY5QnGZysIBYoeSsl5qQzrSj/cgNrfuEzlWBfwA+EjrZyWUvpAAAAABJRU5ErkJggg=='
],
currentBadge: ''
}
},
props: ['sidebarItems'],
components: { PageEdit, PageNav, ArticleInfo, Catalogue, UpdateArticle, Timeline, Footer, RightMenu},
created() {
this.updateBarConfig = this.$themeConfig.updateBar
if (this.$themeConfig.titleBadgeIcons) {
this.badges = this.$themeConfig.titleBadgeIcons
}
this.currentBadge = this.getBadge()
},
mounted() {
console.log(this.$refs)
watch: {
'$route.path'() {
this.currentBadge = this.getBadge()
}
},
computed: {
isShowUpdateBar() {
return this.updateBarConfig && this.updateBarConfig.isShow === false ? false : true
},
showTitle() {
return !this.$frontmatter.pageComponent
},
showRightMenu(){
return this.$page.headers && (this.$frontmatter && this.$frontmatter.sidebar && this.$frontmatter.sidebar !== false) !== false
},
@ -68,6 +88,9 @@ export default {
}
},
methods: {
getBadge() {
return this.badges[Math.floor(Math.random() * this.badges.length)]
},
isArticle() {
return this.$frontmatter.article !== false
}
@ -91,6 +114,11 @@ export default {
.theme-vdoing-wrapper
.content-wrapper
position relative
h1 img
margin-bottom -0.2rem
max-width 2.2rem
max-height 2.2rem
/**
* 右侧菜单的自适应

View File

@ -1,15 +1,21 @@
<template>
<footer class="page-edit">
<div class="page-edit">
<div class="edit-link" v-if="editLink">
<a :href="editLink" target="_blank" rel="noopener noreferrer">{{ editLinkText }}</a>
<OutboundLink />
</div>
<div class="tags" v-if="tags && tags[0]">
<router-link to="/" v-for="(item, index) in tags" :key="index" title="标签">
#{{item}}
</router-link>
</div>
<div class="last-updated" v-if="lastUpdated">
<span class="prefix">{{ lastUpdatedText }}:</span>
<span class="time">{{ lastUpdated }}</span>
</div>
</footer>
</div>
</template>
<script>
import isNil from 'lodash/isNil'
@ -18,6 +24,10 @@ import { endingSlashRE, outboundRE } from '../util'
export default {
name: 'PageEdit',
computed: {
tags() {
return this.$frontmatter.tags
},
lastUpdated () {
return this.$page.lastUpdated
},
@ -105,8 +115,21 @@ export default {
.edit-link
display inline-block
float left
margin-right 2rem
a
margin-right 0.25rem
.tags
float left
a
margin-right .8rem
color var(--textLightenColor)
padding 0.2rem 0.7rem
font-size 0.9em
background-color rgba(128,128,128,0.08)
border-radius 3px
opacity .8
.last-updated
float right
font-size 0.9em
@ -120,11 +143,11 @@ export default {
@media (max-width: $MQMobile)
.page-edit
.edit-link
margin-bottom 0.5rem
.edit-link,.tags
margin-bottom .5rem
.last-updated
width 100%
font-size 0.8em
float none
text-align left
</style>

View File

@ -48,15 +48,6 @@
<script>
export default {
created() {
console.log(this.$sortPosts)
},
methods: {
// getAuthor(item) {
// console.log(item)
// item
// }
}
}
</script>

View File

@ -0,0 +1,201 @@
<template>
<div class="tags-wrapper card-box">
<router-link to="/" class="title iconfont icon-biaoqian1" title="全部标签">
热门标签
</router-link>
<div class="tags">
<router-link to="/" v-for="(item, index) in tags" :key="index">
{{item.key}}
</router-link>
<router-link to="/" v-if="showMore()">
更多...
</router-link>
</div>
</div>
</template>
<script>
const MAXLEN = 50
export default {
computed: {
tags() {
const test = [
{key: "test", length: 1},
{key: "博客博客博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "testtest", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "githubgithub", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1},
{key: "test", length: 1},
{key: "博客", length: 2},
{key: "css", length: 1},
{key: "github", length: 1}
];
this.$categoriesAndTags.tags = test
return this.$categoriesAndTags.tags.slice(0, MAXLEN)
}
},
methods: {
showMore() {
console.log(this.$categoriesAndTags.tags.length > MAXLEN)
return this.$categoriesAndTags.tags.length > MAXLEN
}
}
}
</script>
<style lang='stylus'>
.tags-wrapper
.title
color var(--textColor)
opacity .8
font-size 1.2rem
&:hover
color $accentColor
.tags
padding-top .5rem
text-align justify
a
color var(--textColor)
opacity .6
font-size .95rem
display inline-block
padding 0 .2rem 0 .1rem
&:hover
color $accentColor
opacity 1
text-decoration underline
</style>

View File

@ -1,7 +1,7 @@
<template>
<div class="theme-container">
<div class="theme-vdoing-content">
<h1>404</h1>
<span>404</span>
<blockquote>{{ getMsg() }}</blockquote>
<router-link to="/">返回首页</router-link>
</div>
@ -27,8 +27,8 @@ export default {
<style lang="stylus" scoped>
.theme-vdoing-content
margin 0 auto
h1
margin 3rem auto
span
font-size 8rem
color $accentColor
</style>

View File

@ -76,6 +76,17 @@ export default {
themeMode: 'light'
}
},
beforeMount(){
//
const social = this.$themeConfig.social
if(social && social.iconfontCssFile ) {
let linkElm = document.createElement("link")
linkElm.setAttribute('rel', 'stylesheet');
linkElm.setAttribute("type", "text/css")
linkElm.setAttribute("href", social.iconfontCssFile)
document.head.appendChild(linkElm)
}
},
computed: {
showRightMenu() {
const { headers } = this.$page

View File

@ -1,5 +1,5 @@
//
@import '//at.alicdn.com/t/font_1678482_hmeznrrjf56.css'
@import '//at.alicdn.com/t/font_1678482_gesz4ocax96.css'
@require './config'
@require './code'
@ -46,44 +46,9 @@ a,input,button
border-radius 5px
background var(--bg)
box-shadow 0 1px 3px 0 rgba(0,0,30,.1), 1px 2px 4px 0 rgba(0,0,0,.1)
.blur
backdrop-filter saturate(200%) blur(20px)
//
// .hover-tip
// position relative
// &::before,
// &::after
// position absolute
// left 50%
// top 100%
// opacity 0
// visibility hidden
// transform translate3d(0, 20px, 0)
// transition all .3s
// z-index 999
// &::before
// margin 0 0 12px -35px
// border-radius 5px
// width 70px
// height 28px
// background-color rgba(#000, .5)
// line-height 28px
// text-align center
// font-size .8rem
// color #fff!important
// content attr(data-title)
// &::after
// margin -10px 0 0 -5px
// border 5px solid transparent
// border-bottom-color rgba(#000, .5)
// width 0
// height 0
// content ""
// &:hover
// &::before,
// &::after
// opacity 1
// visibility visible
// transform translate3d(0, 12px, 0)
.page
transition padding .2s ease
@ -96,7 +61,7 @@ a,input,button
left 0
right 0
height $navbarHeight
background-color var(--bg)
background-color var(--blurBg)
box-sizing border-box
box-shadow 0 2px 5px rgba(0,0,0,.06)
@ -206,6 +171,9 @@ h1, h2, h3, h4, h5, h6
h1
font-size 1.8rem
{$contentClass}:not(.custom) > & // h1
&:first-child
display none
h2
font-size 1.5rem

View File

@ -46,7 +46,8 @@ $cardLayout = 1200px // 卡片式布局响应节点
//
.theme-mode-light
--bg: #fff
--bg: rgb(255,255,255)
--blurBg: rgba(255,255,255,.9)
--textColor: #004050
--textLightenColor: #0085AD
--sidebarBg: rgba(255,255,255,.8)
@ -59,6 +60,7 @@ $cardLayout = 1200px // 卡片式布局响应节点
//
.theme-mode-dark
--bg: rgb(30,30,34)
--blurBg: rgba(30,30,34,.8)
--textColor: rgb(140,140,150)
--textLightenColor: #0085AD
--sidebarBg: rgba(120,120,120,.1)
@ -70,10 +72,11 @@ $cardLayout = 1200px // 卡片式布局响应节点
//
.theme-mode-read
--bg: #f5f5d5
--bg: rgb(245,245,213)
--blurBg: rgba(245,245,213,.9)
--textColor: #004050
--textLightenColor: #0085AD
--sidebarBg: #f5f5d5
--sidebarBg: rgb(245,245,213)
--pageBg: rgba(220,220,220,0.2)
--borderColor: rgba(0,0,0,.15)
--codeBgColor: #282c34