v1.5.0
This commit is contained in:
parent
35eba2ecb8
commit
e14d02f952
|
|
@ -8,7 +8,7 @@
|
||||||
<a href="https://www.npmjs.com/package/vuepress-theme-vdoing"><img alt="npm" src="https://img.shields.io/npm/v/vuepress-theme-vdoing"></a>
|
<a href="https://www.npmjs.com/package/vuepress-theme-vdoing"><img alt="npm" src="https://img.shields.io/npm/v/vuepress-theme-vdoing"></a>
|
||||||
<a href="https://github.com/xugaoyi/vuepress-theme-vdoing/stargazers"><img src="https://img.shields.io/github/stars/xugaoyi/vuepress-theme-vdoing?logo=ReverbNation&logoColor=rgba(255,255,255,.6)" alt="GitHub stars"></a>
|
<a href="https://github.com/xugaoyi/vuepress-theme-vdoing/stargazers"><img src="https://img.shields.io/github/stars/xugaoyi/vuepress-theme-vdoing?logo=ReverbNation&logoColor=rgba(255,255,255,.6)" alt="GitHub stars"></a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[文档 (github源)](https://xugaoyi.github.io/vuepress-theme-vdoing-doc/) | [文档 (国内源)](https://doc.xugaoyi.com/vuepress-theme-vdoing-doc/) | [效果:Evan's blog](https://xugaoyi.com/)
|
[文档 (github源)](https://xugaoyi.github.io/vuepress-theme-vdoing-doc/) | [文档 (国内源)](https://doc.xugaoyi.com/vuepress-theme-vdoing-doc/) | [效果:Evan's blog](https://xugaoyi.com/)
|
||||||
|
|
||||||
## 介绍
|
## 介绍
|
||||||
1. 这个主题的初衷是打造一个好用的、面向程序员的`知识管理工具`
|
1. 这个主题的初衷是打造一个好用的、面向程序员的`知识管理工具`
|
||||||
|
|
@ -57,8 +57,7 @@ npm run dev # or yarn dev
|
||||||
|
|
||||||
## :sparkling_heart:支持这个项目
|
## :sparkling_heart:支持这个项目
|
||||||
|
|
||||||
我尽己所能地进行开源,并且我尽量回复每个在使用项目时需要帮助的人。很明显,这需要时间,但你可以免费享受这些。
|
如果你正在使用这个项目并感觉良好,或只是想要支持我继续开发,你可以通过如下任意方式支持我:
|
||||||
然而, 如果你正在使用这个项目并感觉良好,或只是想要支持我继续开发,你可以通过如下方式支持我:
|
|
||||||
|
|
||||||
- **Star** 并 分享这个项目 :rocket:
|
- **Star** 并 分享这个项目 :rocket:
|
||||||
- 保留主题 footer(页脚) 的主题链接 :D
|
- 保留主题 footer(页脚) 的主题链接 :D
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ module.exports = {
|
||||||
options: {
|
options: {
|
||||||
clientID: 'a6e1355287947096b88b',
|
clientID: 'a6e1355287947096b88b',
|
||||||
clientSecret: 'f0e77d070fabfcd5af95bebb82b2d574d7248d71',
|
clientSecret: 'f0e77d070fabfcd5af95bebb82b2d574d7248d71',
|
||||||
repo: 'vuepress-theme-vdoing', // GitHub 仓库
|
repo: 'blog-gitalk-comment', // GitHub 仓库
|
||||||
owner: 'xugaoyi', // GitHub仓库所有者
|
owner: 'xugaoyi', // GitHub仓库所有者
|
||||||
admin: ['xugaoyi'], // 对仓库有写权限的人
|
admin: ['xugaoyi'], // 对仓库有写权限的人
|
||||||
// distractionFreeMode: true,
|
// distractionFreeMode: true,
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ article: false
|
||||||
|
|
||||||
|
|
||||||
### 🐼Me
|
### 🐼Me
|
||||||
落魄Web前端工程师
|
web前端小学生
|
||||||
|
|
||||||
#### 技能
|
#### 技能
|
||||||
* 熟悉 JavaScript、HTML、CSS、Vue 的拼写
|
* 熟悉 JavaScript、HTML、CSS、Vue 的拼写
|
||||||
* 了解 Linux、windows、macOS 的开关机方式
|
* 了解 Linux、windows、macOS 的开关机方式
|
||||||
|
|
@ -39,7 +40,8 @@ article: false
|
||||||
- **WeChat or QQ**: <a :href="qqUrl" class='qq'>894072666</a>
|
- **WeChat or QQ**: <a :href="qqUrl" class='qq'>894072666</a>
|
||||||
- **Email**: <a href="mailto:894072666@qq.com">894072666@qq.com</a>
|
- **Email**: <a href="mailto:894072666@qq.com">894072666@qq.com</a>
|
||||||
- **GitHub**: <https://github.com/xugaoyi>
|
- **GitHub**: <https://github.com/xugaoyi>
|
||||||
- **Vdoing官方交流QQ群**:694387113
|
- **Vdoing主题文档:**<https://doc.xugaoyi.com/vuepress-theme-vdoing-doc/>
|
||||||
|
- **Vdoing交流QQ群**:694387113
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
"vuepress-plugin-one-click-copy": "^1.0.2",
|
"vuepress-plugin-one-click-copy": "^1.0.2",
|
||||||
"vuepress-plugin-thirdparty-search": "^1.0.2",
|
"vuepress-plugin-thirdparty-search": "^1.0.2",
|
||||||
"vuepress-plugin-zooming": "^1.1.7",
|
"vuepress-plugin-zooming": "^1.1.7",
|
||||||
"vuepress-theme-vdoing": "^1.4.4",
|
"vuepress-theme-vdoing": "^1.5.0",
|
||||||
"yamljs": "^0.3.0"
|
"yamljs": "^0.3.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
id="algolia-search-input"
|
id="algolia-search-input"
|
||||||
class="search-query"
|
class="search-query"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
>
|
/>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ export default {
|
||||||
import(/* webpackChunkName: "docsearch" */ 'docsearch.js/dist/cdn/docsearch.min.css')
|
import(/* webpackChunkName: "docsearch" */ 'docsearch.js/dist/cdn/docsearch.min.css')
|
||||||
]).then(([docsearch]) => {
|
]).then(([docsearch]) => {
|
||||||
docsearch = docsearch.default
|
docsearch = docsearch.default
|
||||||
const { algoliaOptions = {}} = userOptions
|
const { algoliaOptions = {} } = userOptions
|
||||||
docsearch(Object.assign(
|
docsearch(Object.assign(
|
||||||
{},
|
{},
|
||||||
userOptions,
|
userOptions,
|
||||||
|
|
@ -127,8 +127,7 @@ export default {
|
||||||
.ds-cursor .algolia-docsearch-suggestion--content
|
.ds-cursor .algolia-docsearch-suggestion--content
|
||||||
background-color #e7edf3 !important
|
background-color #e7edf3 !important
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
|
@media (min-width $MQMobile)
|
||||||
@media (min-width: $MQMobile)
|
|
||||||
.algolia-search-wrapper
|
.algolia-search-wrapper
|
||||||
.algolia-autocomplete
|
.algolia-autocomplete
|
||||||
.algolia-docsearch-suggestion
|
.algolia-docsearch-suggestion
|
||||||
|
|
@ -144,8 +143,7 @@ export default {
|
||||||
vertical-align top
|
vertical-align top
|
||||||
.ds-dropdown-menu
|
.ds-dropdown-menu
|
||||||
min-width 515px !important
|
min-width 515px !important
|
||||||
|
@media (max-width $MQMobile)
|
||||||
@media (max-width: $MQMobile)
|
|
||||||
.algolia-search-wrapper
|
.algolia-search-wrapper
|
||||||
.ds-dropdown-menu
|
.ds-dropdown-menu
|
||||||
min-width calc(100vw - 4rem) !important
|
min-width calc(100vw - 4rem) !important
|
||||||
|
|
@ -156,12 +154,11 @@ export default {
|
||||||
padding 0 !important
|
padding 0 !important
|
||||||
background white !important
|
background white !important
|
||||||
.algolia-docsearch-suggestion--subcategory-column-text:after
|
.algolia-docsearch-suggestion--subcategory-column-text:after
|
||||||
content " > "
|
content ' > '
|
||||||
font-size 10px
|
font-size 10px
|
||||||
line-height 14.4px
|
line-height 14.4px
|
||||||
display inline-block
|
display inline-block
|
||||||
width 5px
|
width 5px
|
||||||
margin -3px 3px 0
|
margin -3px 3px 0
|
||||||
vertical-align middle
|
vertical-align middle
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,14 @@
|
||||||
<div class="custom-page archives-page">
|
<div class="custom-page archives-page">
|
||||||
<div class="theme-vdoing-wrapper">
|
<div class="theme-vdoing-wrapper">
|
||||||
<h1>
|
<h1>
|
||||||
<img :src="currentBadge" v-if="$themeConfig.titleBadge === false ? false : true">
|
<img
|
||||||
|
:src="currentBadge"
|
||||||
|
v-if="$themeConfig.titleBadge === false ? false : true"
|
||||||
|
/>
|
||||||
{{this.$page.title}}
|
{{this.$page.title}}
|
||||||
</h1>
|
</h1>
|
||||||
<ul>
|
<ul>
|
||||||
<template
|
<template v-for="(item, index) in postsList">
|
||||||
v-for="(item, index) in postsList"
|
|
||||||
>
|
|
||||||
<li
|
<li
|
||||||
class="year"
|
class="year"
|
||||||
v-if="(year = getYear(index)) !== getYear(index-1)"
|
v-if="(year = getYear(index)) !== getYear(index-1)"
|
||||||
|
|
@ -16,13 +17,9 @@
|
||||||
>
|
>
|
||||||
<h2>{{year}}</h2>
|
<h2>{{year}}</h2>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li :key="index">
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<router-link :to="item.path">
|
<router-link :to="item.path">
|
||||||
<span>
|
<span>{{ getDate(item) }}</span>
|
||||||
{{ getDate(item) }}
|
|
||||||
</span>
|
|
||||||
{{item.title}}
|
{{item.title}}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -39,7 +36,7 @@ import TitleBadgeMixin from '../mixins/titleBadge'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [TitleBadgeMixin],
|
mixins: [TitleBadgeMixin],
|
||||||
data() {
|
data () {
|
||||||
return {
|
return {
|
||||||
postsList: [],
|
postsList: [],
|
||||||
|
|
||||||
|
|
@ -47,48 +44,48 @@ export default {
|
||||||
currentPage: 1// 当前页
|
currentPage: 1// 当前页
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created () {
|
||||||
this.getPageData()
|
this.getPageData()
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted () {
|
||||||
|
|
||||||
window.addEventListener('scroll', debounce(() => {
|
window.addEventListener('scroll', debounce(() => {
|
||||||
if(this.postsList.length < this.$sortPostsByDate.length) {
|
if (this.postsList.length < this.$sortPostsByDate.length) {
|
||||||
const docEl = document.documentElement
|
const docEl = document.documentElement
|
||||||
const docBody = document.body
|
const docBody = document.body
|
||||||
const scrollTop = docEl.scrollTop || docBody.scrollTop;
|
const scrollTop = docEl.scrollTop || docBody.scrollTop;
|
||||||
const clientHeight = docEl.clientHeight || docBody.clientHeight;
|
const clientHeight = docEl.clientHeight || docBody.clientHeight;
|
||||||
const scrollHeight = docEl.scrollHeight || docBody.scrollHeight;
|
const scrollHeight = docEl.scrollHeight || docBody.scrollHeight;
|
||||||
|
|
||||||
if(scrollHeight > clientHeight && scrollTop + clientHeight >= scrollHeight-250) {
|
if (scrollHeight > clientHeight && scrollTop + clientHeight >= scrollHeight - 250) {
|
||||||
this.loadmore()
|
this.loadmore()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}, 200))
|
}, 200))
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getPageData() {
|
getPageData () {
|
||||||
const currentPage = this.currentPage
|
const currentPage = this.currentPage
|
||||||
const perPage = this.perPage
|
const perPage = this.perPage
|
||||||
this.postsList = this.postsList.concat(this.$sortPostsByDate.slice((currentPage-1)*perPage, currentPage*perPage))
|
this.postsList = this.postsList.concat(this.$sortPostsByDate.slice((currentPage - 1) * perPage, currentPage * perPage))
|
||||||
},
|
},
|
||||||
loadmore() {
|
loadmore () {
|
||||||
this.currentPage = this.currentPage+1
|
this.currentPage = this.currentPage + 1
|
||||||
this.getPageData()
|
this.getPageData()
|
||||||
},
|
},
|
||||||
getYear(index) {
|
getYear (index) {
|
||||||
const item = this.postsList[index]
|
const item = this.postsList[index]
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const {frontmatter: { date }} = item
|
const { frontmatter: { date } } = item
|
||||||
if (date && type(date) === 'string') {
|
if (date && type(date) === 'string') {
|
||||||
return date.split(" ")[0].slice(0, 4)
|
return date.split(" ")[0].slice(0, 4)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getDate(item) {
|
getDate (item) {
|
||||||
const {frontmatter: { date }} = item
|
const { frontmatter: { date } } = item
|
||||||
if (date && type(date) === 'string') {
|
if (date && type(date) === 'string') {
|
||||||
return date.split(" ")[0].slice(5, 10)
|
return date.split(" ")[0].slice(5, 10)
|
||||||
}
|
}
|
||||||
|
|
@ -100,14 +97,13 @@ export default {
|
||||||
<style lang='stylus'>
|
<style lang='stylus'>
|
||||||
@require '../styles/wrapper.styl'
|
@require '../styles/wrapper.styl'
|
||||||
|
|
||||||
|
|
||||||
.archives-page
|
.archives-page
|
||||||
.theme-vdoing-wrapper
|
.theme-vdoing-wrapper
|
||||||
@extend $vdoing-wrapper
|
@extend $vdoing-wrapper
|
||||||
position relative
|
position relative
|
||||||
@media (min-width $contentWidth + 80)
|
@media (min-width $contentWidth + 80)
|
||||||
margin-top 1.5rem!important
|
margin-top 1.5rem !important
|
||||||
ul,li
|
ul, li
|
||||||
margin 0
|
margin 0
|
||||||
padding 0
|
padding 0
|
||||||
li
|
li
|
||||||
|
|
@ -120,39 +116,35 @@ export default {
|
||||||
&.year:not(:first-child)
|
&.year:not(:first-child)
|
||||||
margin-top 3.5rem
|
margin-top 3.5rem
|
||||||
h2
|
h2
|
||||||
margin-bottom .8rem
|
margin-bottom 0.8rem
|
||||||
font-weight 400
|
font-weight 400
|
||||||
padding .5rem 0
|
padding 0.5rem 0
|
||||||
a
|
a
|
||||||
display block
|
display block
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
transition padding .3s
|
transition padding 0.3s
|
||||||
padding .5rem 2rem
|
padding 0.5rem 2rem
|
||||||
line-height 1.2rem
|
line-height 1.2rem
|
||||||
&:hover
|
&:hover
|
||||||
padding-left 2.5rem
|
padding-left 2.5rem
|
||||||
color $accentColor
|
color $accentColor
|
||||||
background lighten($accentColor, 90%)
|
background #f9f9f9
|
||||||
@media (max-width $contentWidth + 80)
|
@media (max-width $contentWidth + 80)
|
||||||
padding .5rem 1rem
|
padding 0.5rem 1rem
|
||||||
font-weight: normal;
|
font-weight normal
|
||||||
&:hover
|
&:hover
|
||||||
padding-left 1.5rem
|
padding-left 1.5rem
|
||||||
span
|
span
|
||||||
opacity .6
|
opacity 0.6
|
||||||
font-size .85rem
|
font-size 0.85rem
|
||||||
font-weight 400
|
font-weight 400
|
||||||
margin-right .3rem
|
margin-right 0.3rem
|
||||||
.loadmore
|
.loadmore
|
||||||
text-align center
|
text-align center
|
||||||
margin-top 1rem
|
margin-top 1rem
|
||||||
opacity .5
|
opacity 0.5
|
||||||
|
.theme-mode-dark .archives-page .theme-vdoing-wrapper li a:hover, .theme-mode-read .archives-page .theme-vdoing-wrapper li a:hover
|
||||||
.theme-mode-dark .archives-page .theme-vdoing-wrapper li a:hover,
|
|
||||||
.theme-mode-read .archives-page .theme-vdoing-wrapper li a:hover
|
|
||||||
background var(--customBlockBg)
|
background var(--customBlockBg)
|
||||||
|
|
||||||
|
|
||||||
.hide-navbar
|
.hide-navbar
|
||||||
.archives-page
|
.archives-page
|
||||||
.theme-vdoing-wrapper
|
.theme-vdoing-wrapper
|
||||||
|
|
|
||||||
|
|
@ -1,59 +1,102 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="articleInfo-wrap">
|
<div class="articleInfo-wrap">
|
||||||
<div class="articleInfo">
|
<div class="articleInfo">
|
||||||
<ul class="breadcrumbs" v-if="articleInfo.classify1 && articleInfo.classify1 !== '_posts'">
|
<ul
|
||||||
|
class="breadcrumbs"
|
||||||
|
v-if="articleInfo.classify1 && articleInfo.classify1 !== '_posts'"
|
||||||
|
>
|
||||||
<li>
|
<li>
|
||||||
<router-link to="/" class="iconfont icon-home" title="首页" />
|
<router-link
|
||||||
|
to="/"
|
||||||
|
class="iconfont icon-home"
|
||||||
|
title="首页"
|
||||||
|
/>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<router-link v-if="articleInfo.cataloguePermalink" :to="articleInfo.cataloguePermalink" :title="articleInfo.classify1+'-目录页'">{{articleInfo.classify1}}</router-link>
|
<router-link
|
||||||
<router-link v-else-if="$themeConfig.category !== false" :to="`/categories/?category=${articleInfo.classify1}`" title="分类">{{articleInfo.classify1}}</router-link>
|
v-if="articleInfo.cataloguePermalink"
|
||||||
|
:to="articleInfo.cataloguePermalink"
|
||||||
|
:title="articleInfo.classify1+'-目录页'"
|
||||||
|
>{{articleInfo.classify1}}</router-link>
|
||||||
|
<router-link
|
||||||
|
v-else-if="$themeConfig.category !== false"
|
||||||
|
:to="`/categories/?category=${encodeURIComponent(articleInfo.classify1)}`"
|
||||||
|
title="分类"
|
||||||
|
>{{articleInfo.classify1}}</router-link>
|
||||||
<span v-else>{{ articleInfo.classify1 }}</span>
|
<span v-else>{{ articleInfo.classify1 }}</span>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="articleInfo.classify2">
|
<li v-if="articleInfo.classify2">
|
||||||
<router-link v-if="articleInfo.cataloguePermalink" :to="articleInfo.cataloguePermalink + '/#' + encodeUrl(articleInfo.classify2)" :title="articleInfo.classify1+'#'+articleInfo.classify2">{{articleInfo.classify2}}</router-link>
|
<router-link
|
||||||
<router-link v-else-if="$themeConfig.category !== false" :to="`/categories/?category=${articleInfo.classify2}`" title="分类">{{articleInfo.classify2}}</router-link>
|
v-if="articleInfo.cataloguePermalink"
|
||||||
|
:to="articleInfo.cataloguePermalink + '/#' + articleInfo.classify2"
|
||||||
|
:title="articleInfo.classify1+'#'+articleInfo.classify2"
|
||||||
|
>{{articleInfo.classify2}}</router-link>
|
||||||
|
<router-link
|
||||||
|
v-else-if="$themeConfig.category !== false"
|
||||||
|
:to="`/categories/?category=${encodeURIComponent(articleInfo.classify2)}`"
|
||||||
|
title="分类"
|
||||||
|
>{{articleInfo.classify2}}</router-link>
|
||||||
<span v-else>{{articleInfo.classify2}}</span>
|
<span v-else>{{articleInfo.classify2}}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="author iconfont icon-touxiang" title="作者" v-if="articleInfo.author">
|
<div
|
||||||
<a :href="articleInfo.author.href || articleInfo.author.link" v-if="articleInfo.author.href || articleInfo.author.link && typeof(articleInfo.author.link) === 'string'" target="_blank" class="beLink" title="作者">{{articleInfo.author.name}}</a>
|
class="author iconfont icon-touxiang"
|
||||||
<a v-else href="javascript:;">{{articleInfo.author.name || articleInfo.author}}</a>
|
title="作者"
|
||||||
|
v-if="articleInfo.author"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
:href="articleInfo.author.href || articleInfo.author.link"
|
||||||
|
v-if="articleInfo.author.href || articleInfo.author.link && typeof(articleInfo.author.link) === 'string'"
|
||||||
|
target="_blank"
|
||||||
|
class="beLink"
|
||||||
|
title="作者"
|
||||||
|
>{{articleInfo.author.name}}</a>
|
||||||
|
<a
|
||||||
|
v-else
|
||||||
|
href="javascript:;"
|
||||||
|
>{{articleInfo.author.name || articleInfo.author}}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="date iconfont icon-riqi" title="创建时间" v-if="articleInfo.date">
|
<div
|
||||||
<a href="javascript:;" >{{articleInfo.date}}</a>
|
class="date iconfont icon-riqi"
|
||||||
|
title="创建时间"
|
||||||
|
v-if="articleInfo.date"
|
||||||
|
>
|
||||||
|
<a href="javascript:;">{{articleInfo.date}}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="date iconfont icon-wenjian" title="分类" v-if="$themeConfig.category !== false && !(articleInfo.classify1 && articleInfo.classify1 !== '_posts') && articleInfo.categories">
|
<div
|
||||||
<router-link :to="`/categories/?category=${item}`" v-for="(item, index) in articleInfo.categories" :key="index">
|
class="date iconfont icon-wenjian"
|
||||||
{{item}}
|
title="分类"
|
||||||
</router-link>
|
v-if="$themeConfig.category !== false && !(articleInfo.classify1 && articleInfo.classify1 !== '_posts') && articleInfo.categories"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="`/categories/?category=${encodeURIComponent(item)}`"
|
||||||
|
v-for="(item, index) in articleInfo.categories"
|
||||||
|
:key="index"
|
||||||
|
>{{item + ' '}}</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
|
||||||
import encodeMixin from '../mixins/encodeUrl'
|
|
||||||
|
|
||||||
|
<script>
|
||||||
export default {
|
export default {
|
||||||
mixins: [encodeMixin],
|
data () {
|
||||||
data() {
|
|
||||||
return {
|
return {
|
||||||
articleInfo: {}
|
articleInfo: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created () {
|
||||||
this.articleInfo = this.getPageInfo()
|
this.articleInfo = this.getPageInfo()
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route.path'() {
|
'$route.path' () {
|
||||||
this.articleInfo = this.getPageInfo()
|
this.articleInfo = this.getPageInfo()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getPageInfo() {
|
getPageInfo () {
|
||||||
const pageInfo = this.$page
|
const pageInfo = this.$page
|
||||||
const { relativePath } = pageInfo
|
const { relativePath } = pageInfo
|
||||||
const { sidebar } = this.$themeConfig
|
const { sidebar } = this.$themeConfig
|
||||||
|
|
@ -65,7 +108,7 @@ export default {
|
||||||
const classify2 = relativePathArr.length > 2 ? relativePathArr[1].split('.')[1] : undefined// 文章二级分类名称
|
const classify2 = relativePathArr.length > 2 ? relativePathArr[1].split('.')[1] : undefined// 文章二级分类名称
|
||||||
|
|
||||||
const cataloguePermalink = sidebar && sidebar.catalogue ? sidebar.catalogue[classify1] : undefined// 目录页永久链接
|
const cataloguePermalink = sidebar && sidebar.catalogue ? sidebar.catalogue[classify1] : undefined// 目录页永久链接
|
||||||
|
|
||||||
const author = this.$frontmatter.author || this.$themeConfig.author // 作者
|
const author = this.$frontmatter.author || this.$themeConfig.author // 作者
|
||||||
let date = (pageInfo.frontmatter.date || '').split(' ')[0] // 文章创建时间
|
let date = (pageInfo.frontmatter.date || '').split(' ')[0] // 文章创建时间
|
||||||
|
|
||||||
|
|
@ -90,19 +133,19 @@ export default {
|
||||||
|
|
||||||
.articleInfo-wrap
|
.articleInfo-wrap
|
||||||
@extend $wrapper
|
@extend $wrapper
|
||||||
position: relative
|
position relative
|
||||||
z-index: 1
|
z-index 1
|
||||||
color #888
|
color #888
|
||||||
.articleInfo
|
.articleInfo
|
||||||
overflow hidden
|
overflow hidden
|
||||||
font-size .92rem
|
font-size 0.92rem
|
||||||
.breadcrumbs
|
.breadcrumbs
|
||||||
margin 0
|
margin 0
|
||||||
padding 0
|
padding 0
|
||||||
overflow hidden
|
overflow hidden
|
||||||
display inline-block
|
display inline-block
|
||||||
line-height 2rem
|
line-height 2rem
|
||||||
@media (max-width: 960px)
|
@media (max-width 960px)
|
||||||
width 100%
|
width 100%
|
||||||
li
|
li
|
||||||
list-style-type none
|
list-style-type none
|
||||||
|
|
@ -118,7 +161,7 @@ export default {
|
||||||
a
|
a
|
||||||
color #888
|
color #888
|
||||||
&:before
|
&:before
|
||||||
font-size .92rem
|
font-size 0.92rem
|
||||||
&:hover
|
&:hover
|
||||||
color $accentColor
|
color $accentColor
|
||||||
.icon-home
|
.icon-home
|
||||||
|
|
@ -126,13 +169,13 @@ export default {
|
||||||
.info
|
.info
|
||||||
float right
|
float right
|
||||||
line-height 32px
|
line-height 32px
|
||||||
@media (max-width: 960px)
|
@media (max-width 960px)
|
||||||
float left
|
float left
|
||||||
div
|
div
|
||||||
float left
|
float left
|
||||||
margin-left 20px
|
margin-left 20px
|
||||||
font-size .8rem
|
font-size 0.8rem
|
||||||
@media (max-width: 960px)
|
@media (max-width 960px)
|
||||||
margin 0 20px 0 0
|
margin 0 20px 0 0
|
||||||
&:before
|
&:before
|
||||||
margin-right 3px
|
margin-right 3px
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<aside class="blogger-wrapper card-box">
|
<aside class="blogger-wrapper card-box">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<img :src="blogger.avatar" alt="头像" title="我好看吗">
|
<img
|
||||||
|
:src="blogger.avatar"
|
||||||
|
alt="头像"
|
||||||
|
title="我好看吗"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="icons" v-if="social">
|
<div
|
||||||
|
class="icons"
|
||||||
|
v-if="social"
|
||||||
|
>
|
||||||
<a
|
<a
|
||||||
v-for="(item, index) in social.icons"
|
v-for="(item, index) in social.icons"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
|
@ -15,12 +22,8 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="blogger">
|
<div class="blogger">
|
||||||
<span class="name">
|
<span class="name">{{blogger.name}}</span>
|
||||||
{{blogger.name}}
|
<span class="slogan">{{blogger.slogan}}</span>
|
||||||
</span>
|
|
||||||
<span class="slogan">
|
|
||||||
{{blogger.slogan}}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -28,10 +31,10 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
blogger() {
|
blogger () {
|
||||||
return this.$themeConfig.blogger
|
return this.$themeConfig.blogger
|
||||||
},
|
},
|
||||||
social() {
|
social () {
|
||||||
return this.$themeConfig.social
|
return this.$themeConfig.social
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -64,15 +67,14 @@ export default {
|
||||||
display block
|
display block
|
||||||
float left
|
float left
|
||||||
text-align center
|
text-align center
|
||||||
opacity .8
|
opacity 0.8
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
color $accentColor
|
color $accentColor
|
||||||
.blogger
|
.blogger
|
||||||
margin 12px 0 2px 0
|
margin 12px 0 2px 0
|
||||||
.name
|
.name
|
||||||
font-size 1.4rem
|
font-size 1.4rem
|
||||||
display: block
|
display block
|
||||||
margin-bottom 6px
|
margin-bottom 6px
|
||||||
.slogan
|
.slogan
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="body-bg" :style="`background: url(${bgImg}) center center / cover no-repeat;opacity:${opacity}`"></div>
|
<div
|
||||||
|
class="body-bg"
|
||||||
|
:style="`background: url(${bgImg}) center center / cover no-repeat;opacity:${opacity}`"
|
||||||
|
></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { type } from '../util'
|
import { type } from '../util'
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data () {
|
||||||
return {
|
return {
|
||||||
bgImg: '',
|
bgImg: '',
|
||||||
opacity: 0.5
|
opacity: 0.5
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted () {
|
||||||
let { bodyBgImg, bodyBgImgOpacity } = this.$themeConfig
|
let { bodyBgImg, bodyBgImgOpacity } = this.$themeConfig
|
||||||
|
|
||||||
if (type(bodyBgImg) === 'string') {
|
if (type(bodyBgImg) === 'string') {
|
||||||
|
|
@ -23,7 +26,7 @@ export default {
|
||||||
this.bgImg = bodyBgImg[count]
|
this.bgImg = bodyBgImg[count]
|
||||||
clearInterval(timer)
|
clearInterval(timer)
|
||||||
timer = setInterval(() => {
|
timer = setInterval(() => {
|
||||||
if (++count >= bodyBgImg.length ) {
|
if (++count >= bodyBgImg.length) {
|
||||||
count = 0
|
count = 0
|
||||||
}
|
}
|
||||||
this.bgImg = bodyBgImg[count]
|
this.bgImg = bodyBgImg[count]
|
||||||
|
|
@ -46,5 +49,5 @@ export default {
|
||||||
z-index -999999
|
z-index -999999
|
||||||
height 100vh
|
height 100vh
|
||||||
width 100vw
|
width 100vw
|
||||||
transition background .5s
|
transition background 0.5s
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -22,16 +22,20 @@
|
||||||
@click="showModeBox = true"
|
@click="showModeBox = true"
|
||||||
>
|
>
|
||||||
<transition name="mode">
|
<transition name="mode">
|
||||||
<ul class="select-box" ref="modeBox" v-show="showModeBox" @click.stop @touchstart.stop>
|
<ul
|
||||||
|
class="select-box"
|
||||||
|
ref="modeBox"
|
||||||
|
v-show="showModeBox"
|
||||||
|
@click.stop
|
||||||
|
@touchstart.stop
|
||||||
|
>
|
||||||
<li
|
<li
|
||||||
v-for="item in modeList"
|
v-for="item in modeList"
|
||||||
:key="item.KEY"
|
:key="item.KEY"
|
||||||
class="iconfont"
|
class="iconfont"
|
||||||
:class="[item.icon, {active: item.KEY === currentMode}]"
|
:class="[item.icon, {active: item.KEY === currentMode}]"
|
||||||
@click="toggleMode(item.KEY)"
|
@click="toggleMode(item.KEY)"
|
||||||
>
|
>{{item.name}}</li>
|
||||||
{{item.name}}
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -44,7 +48,7 @@ import storage from 'good-storage' // 本地存储
|
||||||
const MOBILE_DESKTOP_BREAKPOINT = 719 // refer to config.styl
|
const MOBILE_DESKTOP_BREAKPOINT = 719 // refer to config.styl
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data () {
|
||||||
return {
|
return {
|
||||||
threshold: 100,
|
threshold: 100,
|
||||||
scrollTop: null,
|
scrollTop: null,
|
||||||
|
|
@ -101,27 +105,27 @@ export default {
|
||||||
this.showModeBox = false
|
this.showModeBox = false
|
||||||
}
|
}
|
||||||
window.addEventListener('scroll', debounce(() => {
|
window.addEventListener('scroll', debounce(() => {
|
||||||
if(this.showModeBox) {
|
if (this.showModeBox) {
|
||||||
this.showModeBox = false
|
this.showModeBox = false
|
||||||
}
|
}
|
||||||
}, 100))
|
}, 100))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 移动端对类似:hover效果的处理
|
// 移动端对类似:hover效果的处理
|
||||||
const buttons = document.querySelectorAll('.buttons .button')
|
const buttons = document.querySelectorAll('.buttons .button')
|
||||||
for (let i = 0; i < buttons.length; i++) {
|
for (let i = 0; i < buttons.length; i++) {
|
||||||
const button = buttons[i]
|
const button = buttons[i]
|
||||||
button.addEventListener('touchstart', function(){
|
button.addEventListener('touchstart', function () {
|
||||||
button.classList.add('hover')
|
button.classList.add('hover')
|
||||||
})
|
})
|
||||||
button.addEventListener('touchend', function(){
|
button.addEventListener('touchend', function () {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
button.classList.remove('hover')
|
button.classList.remove('hover')
|
||||||
}, 150)
|
}, 150)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
showToTop () {
|
showToTop () {
|
||||||
|
|
@ -129,7 +133,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleMode(key){
|
toggleMode (key) {
|
||||||
this.currentMode = key
|
this.currentMode = key
|
||||||
this.$emit('toggle-theme-mode', key)
|
this.$emit('toggle-theme-mode', key)
|
||||||
},
|
},
|
||||||
|
|
@ -151,21 +155,21 @@ export default {
|
||||||
this.showCommentBut = this.$frontmatter.comment !== false && this.$frontmatter.home !== true
|
this.showCommentBut = this.$frontmatter.comment !== false && this.$frontmatter.home !== true
|
||||||
this.commentTop = commentEl.offsetTop - 58
|
this.commentTop = commentEl.offsetTop - 58
|
||||||
}
|
}
|
||||||
},500)
|
}, 500)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
scrollToComment() {
|
scrollToComment () {
|
||||||
window.scrollTo({ top: this.commentTop, behavior: 'smooth' })
|
window.scrollTo({ top: this.commentTop, behavior: 'smooth' })
|
||||||
this._textareaEl = document.querySelector(this.COMMENT_SELECTOR_1 + ' textarea') || document.querySelector(this.COMMENT_SELECTOR_2 + ' input') || document.querySelector(this.COMMENT_SELECTOR_3 + ' textarea')
|
this._textareaEl = document.querySelector(this.COMMENT_SELECTOR_1 + ' textarea') || document.querySelector(this.COMMENT_SELECTOR_2 + ' input') || document.querySelector(this.COMMENT_SELECTOR_3 + ' textarea')
|
||||||
if( this._textareaEl && this.getScrollTop() !== this._recordScrollTop) {
|
if (this._textareaEl && this.getScrollTop() !== this._recordScrollTop) {
|
||||||
document.addEventListener("scroll", this._handleListener)
|
document.addEventListener("scroll", this._handleListener)
|
||||||
} else if (this._textareaEl && this.getScrollTop() === this._recordScrollTop) {
|
} else if (this._textareaEl && this.getScrollTop() === this._recordScrollTop) {
|
||||||
this._handleFocus()
|
this._handleFocus()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleListener() {
|
_handleListener () {
|
||||||
clearTimeout(this._scrollTimer)
|
clearTimeout(this._scrollTimer)
|
||||||
this._scrollTimer = setTimeout(() => {
|
this._scrollTimer = setTimeout(() => {
|
||||||
document.removeEventListener('scroll', this._handleListener)
|
document.removeEventListener('scroll', this._handleListener)
|
||||||
|
|
@ -174,7 +178,7 @@ export default {
|
||||||
}, 30)
|
}, 30)
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleFocus() {
|
_handleFocus () {
|
||||||
this._textareaEl.focus()
|
this._textareaEl.focus()
|
||||||
this._textareaEl.classList.add('yellowBorder')
|
this._textareaEl.classList.add('yellowBorder')
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
@ -183,7 +187,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route.path'() {
|
'$route.path' () {
|
||||||
this.showCommentBut = false
|
this.showCommentBut = false
|
||||||
this.getCommentTop()
|
this.getCommentTop()
|
||||||
}
|
}
|
||||||
|
|
@ -192,69 +196,67 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang='stylus'>
|
<style lang='stylus'>
|
||||||
.yellowBorder
|
.yellowBorder
|
||||||
// border: #FFE089 1px solid!important
|
// border: #FFE089 1px solid!important
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
box-shadow 0 0 15px #FFE089!important
|
box-shadow 0 0 15px #FFE089 !important
|
||||||
.buttons
|
.buttons
|
||||||
position fixed
|
position fixed
|
||||||
right 2rem
|
right 2rem
|
||||||
bottom 2.5rem
|
bottom 2.5rem
|
||||||
z-index 11
|
z-index 11
|
||||||
@media (max-width: $MQNarrow)
|
@media (max-width $MQNarrow)
|
||||||
right 1rem
|
right 1rem
|
||||||
bottom 1.5rem
|
bottom 1.5rem
|
||||||
.button
|
.button
|
||||||
width 2.2rem
|
width 2.2rem
|
||||||
height 2.2rem
|
height 2.2rem
|
||||||
line-height 2.2rem
|
line-height 2.2rem
|
||||||
border-radius 50%
|
border-radius 50%
|
||||||
box-shadow 0 2px 6px rgba(0,0,0,.15)
|
box-shadow 0 2px 6px rgba(0, 0, 0, 0.15)
|
||||||
margin-top .9rem
|
margin-top 0.9rem
|
||||||
text-align center
|
text-align center
|
||||||
cursor pointer
|
cursor pointer
|
||||||
transition all .5s
|
transition all 0.5s
|
||||||
background var(--blurBg)
|
background var(--blurBg)
|
||||||
&.hover
|
&.hover
|
||||||
|
background $accentColor
|
||||||
|
box-shadow 0 0 15px $accentColor
|
||||||
|
&:before
|
||||||
|
color #fff
|
||||||
|
@media (any-hover hover)
|
||||||
|
&:hover
|
||||||
background $accentColor
|
background $accentColor
|
||||||
box-shadow 0 0 15px $accentColor
|
box-shadow 0 0 15px $accentColor
|
||||||
&:before
|
&:before
|
||||||
color #fff
|
color #fff
|
||||||
@media (any-hover: hover)
|
.select-box
|
||||||
|
margin 0
|
||||||
|
padding 0.8rem 0
|
||||||
|
position absolute
|
||||||
|
bottom 0rem
|
||||||
|
right 1.5rem
|
||||||
|
background var(--mainBg)
|
||||||
|
border 1px solid var(--borderColor)
|
||||||
|
width 120px
|
||||||
|
border-radius 6px
|
||||||
|
box-shadow 0 0 15px rgba(255, 255, 255, 0.2)
|
||||||
|
li
|
||||||
|
list-style none
|
||||||
|
line-height 2rem
|
||||||
|
font-size 0.95rem
|
||||||
&:hover
|
&:hover
|
||||||
background $accentColor
|
color $accentColor
|
||||||
box-shadow 0 0 15px $accentColor
|
&.active
|
||||||
&:before
|
background-color rgba(150, 150, 150, 0.2)
|
||||||
color #fff
|
color $accentColor
|
||||||
.select-box
|
.mode-enter-active, .mode-leave-active
|
||||||
margin 0
|
transition all 0.3s
|
||||||
padding .8rem 0
|
.mode-enter, .mode-leave-to
|
||||||
position absolute
|
opacity 0
|
||||||
bottom 0rem
|
transform scale(0.8)
|
||||||
right 1.5rem
|
.fade-enter-active, .fade-leave-active
|
||||||
background var(--mainBg)
|
transition opacity 0.2s
|
||||||
border 1px solid var(--borderColor)
|
.fade-enter, .fade-leave-to
|
||||||
width 120px
|
opacity 0
|
||||||
border-radius 6px
|
|
||||||
box-shadow 0 0 15px rgba(255,255,255,.2)
|
|
||||||
li
|
|
||||||
list-style none
|
|
||||||
line-height 2rem
|
|
||||||
font-size .95rem
|
|
||||||
&:hover
|
|
||||||
color $accentColor
|
|
||||||
&.active
|
|
||||||
background-color rgba(150,150,150,.2)
|
|
||||||
color $accentColor
|
|
||||||
|
|
||||||
.mode-enter-active, .mode-leave-active
|
|
||||||
transition all .3s
|
|
||||||
.mode-enter, .mode-leave-to
|
|
||||||
opacity 0
|
|
||||||
transform scale(.8)
|
|
||||||
|
|
||||||
.fade-enter-active, .fade-leave-active
|
|
||||||
transition opacity .2s
|
|
||||||
.fade-enter, .fade-leave-to
|
|
||||||
opacity 0
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -4,27 +4,45 @@
|
||||||
<img :src="$withBase(pageData.imgUrl)" />
|
<img :src="$withBase(pageData.imgUrl)" />
|
||||||
<dl class="column-info">
|
<dl class="column-info">
|
||||||
<dt class="title">{{pageData.title}}</dt>
|
<dt class="title">{{pageData.title}}</dt>
|
||||||
<dd class="description" v-html="pageData.description"></dd>
|
<dd
|
||||||
|
class="description"
|
||||||
|
v-html="pageData.description"
|
||||||
|
></dd>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<div class="catalogue-wrapper" v-if="isStructuring">
|
<div
|
||||||
|
class="catalogue-wrapper"
|
||||||
|
v-if="isStructuring"
|
||||||
|
>
|
||||||
<div class="catalogue-title">目录</div>
|
<div class="catalogue-title">目录</div>
|
||||||
<div class="catalogue-content">
|
<div class="catalogue-content">
|
||||||
<template v-for="(item, index) in getCatalogueList()">
|
<template v-for="(item, index) in getCatalogueList()">
|
||||||
<dl v-if="type(item) === 'array'" :key="index" class="inline">
|
<dl
|
||||||
|
v-if="type(item) === 'array'"
|
||||||
|
:key="index"
|
||||||
|
class="inline"
|
||||||
|
>
|
||||||
<dt>
|
<dt>
|
||||||
<router-link :to="item[2]">{{`${index+1}. ${item[1]}`}}</router-link>
|
<router-link :to="item[2]">{{`${index+1}. ${item[1]}`}}</router-link>
|
||||||
</dt>
|
</dt>
|
||||||
</dl>
|
</dl>
|
||||||
<dl v-else-if="type(item) === 'object'" :key="index">
|
<dl
|
||||||
<dt :id="anchorText = encodeUrl(item.title)">
|
v-else-if="type(item) === 'object'"
|
||||||
<a :href="`#${anchorText}`" class="header-anchor">#</a>
|
:key="index"
|
||||||
|
>
|
||||||
|
<dt :id="anchorText = item.title">
|
||||||
|
<a
|
||||||
|
:href="`#${anchorText}`"
|
||||||
|
class="header-anchor"
|
||||||
|
>#</a>
|
||||||
{{`${index+1}. ${item.title}`}}
|
{{`${index+1}. ${item.title}`}}
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<router-link :to="s[2]" v-for="(s, i) in item.children" :key="i">
|
<router-link
|
||||||
{{`${index+1}-${i+1}. ${s[1]}`}}
|
:to="s[2]"
|
||||||
</router-link>
|
v-for="(s, i) in item.children"
|
||||||
|
:key="i"
|
||||||
|
>{{`${index+1}-${i+1}. ${s[1]}`}}</router-link>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -34,16 +52,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import encodeMixin from '../mixins/encodeUrl'
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [encodeMixin],
|
data () {
|
||||||
data() {
|
|
||||||
return {
|
return {
|
||||||
pageData: null,
|
pageData: null,
|
||||||
isStructuring: true
|
isStructuring: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created () {
|
||||||
this.getPageData()
|
this.getPageData()
|
||||||
|
|
||||||
const sidebar = this.$themeConfig.sidebar
|
const sidebar = this.$themeConfig.sidebar
|
||||||
|
|
@ -53,7 +69,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getPageData() {
|
getPageData () {
|
||||||
const pageComponent = this.$frontmatter.pageComponent
|
const pageComponent = this.$frontmatter.pageComponent
|
||||||
if (pageComponent && pageComponent.data) {
|
if (pageComponent && pageComponent.data) {
|
||||||
this.pageData = {
|
this.pageData = {
|
||||||
|
|
@ -64,23 +80,23 @@ export default {
|
||||||
console.error('请在front matter中设置pageComponent和pageComponent.data数据')
|
console.error('请在front matter中设置pageComponent和pageComponent.data数据')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getCatalogueList() {
|
getCatalogueList () {
|
||||||
const { sidebar } = this.$site.themeConfig
|
const { sidebar } = this.$site.themeConfig
|
||||||
const key = this.$frontmatter.pageComponent.data.key
|
const key = this.$frontmatter.pageComponent.data.key
|
||||||
const catalogueList = sidebar[`/${key}/`]
|
const catalogueList = sidebar[`/${key}/`]
|
||||||
|
|
||||||
if(!catalogueList) {
|
if (!catalogueList) {
|
||||||
console.error('未获取到目录数据,请查看front matter中设置的key是否正确。')
|
console.error('未获取到目录数据,请查看front matter中设置的key是否正确。')
|
||||||
}
|
}
|
||||||
|
|
||||||
return catalogueList
|
return catalogueList
|
||||||
},
|
},
|
||||||
type(o) { // 数据类型检查
|
type (o) { // 数据类型检查
|
||||||
return Object.prototype.toString.call(o).match(/\[object (.*?)\]/)[1].toLowerCase()
|
return Object.prototype.toString.call(o).match(/\[object (.*?)\]/)[1].toLowerCase()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route.path'() {
|
'$route.path' () {
|
||||||
this.getPageData()
|
this.getPageData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +104,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="stylus" rel="stylesheet/stylus">
|
<style scoped lang="stylus" rel="stylesheet/stylus">
|
||||||
dl,dd
|
dl, dd
|
||||||
margin 0
|
margin 0
|
||||||
.column-wrapper
|
.column-wrapper
|
||||||
margin-top 1rem
|
margin-top 1rem
|
||||||
|
|
@ -105,8 +121,8 @@ dl,dd
|
||||||
font-size 1.6rem
|
font-size 1.6rem
|
||||||
.description
|
.description
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
opacity .8
|
opacity 0.8
|
||||||
margin .5rem 0
|
margin 0.5rem 0
|
||||||
.catalogue-wrapper
|
.catalogue-wrapper
|
||||||
.catalogue-title
|
.catalogue-title
|
||||||
font-size 1.45rem
|
font-size 1.45rem
|
||||||
|
|
@ -118,7 +134,7 @@ dl,dd
|
||||||
display inline-block
|
display inline-block
|
||||||
width 50%
|
width 50%
|
||||||
margin-bottom 1rem
|
margin-bottom 1rem
|
||||||
@media (max-width: $MQMobileNarrow)
|
@media (max-width $MQMobileNarrow)
|
||||||
width 100%
|
width 100%
|
||||||
a
|
a
|
||||||
width 100%
|
width 100%
|
||||||
|
|
@ -131,11 +147,11 @@ dl,dd
|
||||||
&:hover .header-anchor
|
&:hover .header-anchor
|
||||||
opacity 1
|
opacity 1
|
||||||
dd
|
dd
|
||||||
margin-top .7rem
|
margin-top 0.7rem
|
||||||
a:not(.header-anchor)
|
a:not(.header-anchor)
|
||||||
margin-bottom .5rem
|
margin-bottom 0.5rem
|
||||||
display inline-block
|
display inline-block
|
||||||
width 50%
|
width 50%
|
||||||
@media (max-width: $MQMobileNarrow)
|
@media (max-width $MQMobileNarrow)
|
||||||
width 100%
|
width 100%
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="categories-wrapper card-box">
|
<div class="categories-wrapper card-box">
|
||||||
<router-link to="/categories/" class="title iconfont icon-wenjianjia" title="全部分类">
|
<router-link
|
||||||
{{ length === 'all' ? '全部分类' : '文章分类' }}
|
to="/categories/"
|
||||||
</router-link>
|
class="title iconfont icon-wenjianjia"
|
||||||
|
title="全部分类"
|
||||||
|
>{{ length === 'all' ? '全部分类' : '文章分类' }}</router-link>
|
||||||
|
|
||||||
<div class="categories">
|
<div class="categories">
|
||||||
<router-link
|
<router-link
|
||||||
:to="`/categories/?category=${item.key}`"
|
:to="`/categories/?category=${encodeURIComponent(item.key)}`"
|
||||||
v-for="(item, index) in categories"
|
v-for="(item, index) in categories"
|
||||||
:key="index"
|
:key="index"
|
||||||
:class="{active: item.key === category}"
|
:class="{active: item.key === category}"
|
||||||
|
|
@ -14,9 +16,11 @@
|
||||||
{{item.key}}
|
{{item.key}}
|
||||||
<span>{{item.length}}</span>
|
<span>{{item.length}}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link to="/categories/" v-if="length !== 'all' && length < categoriesData.length" class="more">
|
<router-link
|
||||||
更多...
|
to="/categories/"
|
||||||
</router-link>
|
v-if="length !== 'all' && length < categoriesData.length"
|
||||||
|
class="more"
|
||||||
|
>更多...</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -38,7 +42,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
categories() {
|
categories () {
|
||||||
if (this.length === 'all') {
|
if (this.length === 'all') {
|
||||||
return this.categoriesData
|
return this.categoriesData
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -50,54 +54,53 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang='stylus'>
|
<style lang='stylus'>
|
||||||
.categories-wrapper
|
.categories-wrapper
|
||||||
.title
|
.title
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
opacity 0.9
|
opacity 0.9
|
||||||
font-size 1.2rem
|
font-size 1.2rem
|
||||||
.categories
|
.categories
|
||||||
margin-top .6rem
|
margin-top 0.6rem
|
||||||
a
|
a
|
||||||
display block
|
display block
|
||||||
padding 8px .3rem 7px .3rem
|
padding 8px 0.3rem 7px 0.3rem
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
opacity .8
|
opacity 0.8
|
||||||
font-size .95rem
|
font-size 0.95rem
|
||||||
line-height .95rem
|
line-height 0.95rem
|
||||||
position relative
|
position relative
|
||||||
transition all .3s
|
transition all 0.3s
|
||||||
border-bottom 1px solid var(--borderColor)
|
border-bottom 1px solid var(--borderColor)
|
||||||
margin-top -1px
|
margin-top -1px
|
||||||
overflow: hidden;
|
overflow hidden
|
||||||
white-space: nowrap;
|
white-space nowrap
|
||||||
text-overflow: ellipsis;
|
text-overflow ellipsis
|
||||||
@media (max-width: $MQMobile)
|
@media (max-width $MQMobile)
|
||||||
font-weight 400
|
font-weight 400
|
||||||
&.more
|
&.more
|
||||||
color $accentColor
|
color $accentColor
|
||||||
&:hover
|
&:hover
|
||||||
color $accentColor
|
color $accentColor
|
||||||
padding-left .6rem
|
padding-left 0.6rem
|
||||||
span
|
span
|
||||||
opacity .8
|
opacity 0.8
|
||||||
span
|
span
|
||||||
float right
|
float right
|
||||||
background-color var(--textColor)
|
background-color var(--textColor)
|
||||||
color var(--mainBg)
|
color var(--mainBg)
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
padding 0 .13rem
|
padding 0 0.13rem
|
||||||
min-width 1rem
|
min-width 1rem
|
||||||
height 1rem
|
height 1rem
|
||||||
line-height 1rem
|
line-height 1rem
|
||||||
font-size .6rem
|
font-size 0.6rem
|
||||||
text-align center
|
text-align center
|
||||||
opacity .6
|
opacity 0.6
|
||||||
transition opacity .3s
|
transition opacity 0.3s
|
||||||
&.active
|
&.active
|
||||||
background $accentColor
|
background $accentColor
|
||||||
color var(--mainBg)
|
color var(--mainBg)
|
||||||
padding-left .8rem
|
padding-left 0.8rem
|
||||||
border-radius 1px
|
border-radius 1px
|
||||||
border-color transparent
|
border-color transparent
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ import Pagination from '@theme/components/Pagination'
|
||||||
import CategoriesBar from '@theme/components/CategoriesBar'
|
import CategoriesBar from '@theme/components/CategoriesBar'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data(){
|
data () {
|
||||||
return {
|
return {
|
||||||
category: '',
|
category: '',
|
||||||
total: 0, // 总长
|
total: 0, // 总长
|
||||||
|
|
@ -47,7 +47,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: { MainLayout, PostList, Pagination, CategoriesBar },
|
components: { MainLayout, PostList, Pagination, CategoriesBar },
|
||||||
mounted() {
|
mounted () {
|
||||||
const queryCategory = this.$route.query.category
|
const queryCategory = this.$route.query.category
|
||||||
if (queryCategory) {
|
if (queryCategory) {
|
||||||
this.category = queryCategory
|
this.category = queryCategory
|
||||||
|
|
@ -70,12 +70,12 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handlePagination(i) { // 分页
|
handlePagination (i) { // 分页
|
||||||
this.currentPage = i
|
this.currentPage = i
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route.query.category'() {
|
'$route.query.category' () {
|
||||||
this.category = this.$route.query.category
|
this.category = this.$route.query.category
|
||||||
if (this.category) {
|
if (this.category) {
|
||||||
this.total = this.$groupPosts.categories[this.category].length
|
this.total = this.$groupPosts.categories[this.category].length
|
||||||
|
|
@ -91,41 +91,40 @@ export default {
|
||||||
|
|
||||||
<style lang='stylus'>
|
<style lang='stylus'>
|
||||||
.categories-page
|
.categories-page
|
||||||
.categories-wrapper
|
.categories-wrapper
|
||||||
position sticky
|
position sticky
|
||||||
top ($navbarHeight + .9rem)
|
top ($navbarHeight + 0.9rem)
|
||||||
max-height calc(100vh - 10rem)
|
max-height calc(100vh - 10rem)
|
||||||
min-height 4.2rem
|
min-height 4.2rem
|
||||||
@media (max-width: $MQMobile)
|
@media (max-width $MQMobile)
|
||||||
display none
|
display none
|
||||||
.categories
|
.categories
|
||||||
padding-right .5rem
|
padding-right 0.5rem
|
||||||
max-height calc(100vh - 14rem)
|
max-height calc(100vh - 14rem)
|
||||||
min-height 2.2rem
|
min-height 2.2rem
|
||||||
overflow-y auto
|
overflow-y auto
|
||||||
transition all .2s
|
transition all 0.2s
|
||||||
position relative
|
position relative
|
||||||
&::-webkit-scrollbar-track-piece
|
&::-webkit-scrollbar-track-piece
|
||||||
background-color:rgba(0,0,0,.05)
|
background-color rgba(0, 0, 0, 0.05)
|
||||||
&::-webkit-scrollbar-thumb:vertical
|
&::-webkit-scrollbar-thumb:vertical
|
||||||
background-color:rgba(0,0,0,.15)
|
background-color rgba(0, 0, 0, 0.15)
|
||||||
&:hover
|
&:hover
|
||||||
&::-webkit-scrollbar-track-piece
|
&::-webkit-scrollbar-track-piece
|
||||||
background-color:rgba(0,0,0,.1)
|
background-color rgba(0, 0, 0, 0.1)
|
||||||
&::-webkit-scrollbar-thumb:vertical
|
&::-webkit-scrollbar-thumb:vertical
|
||||||
background-color:rgba(0,0,0,.25)
|
background-color rgba(0, 0, 0, 0.25)
|
||||||
|
|
||||||
.categories-page
|
.categories-page
|
||||||
.main-left
|
.main-left
|
||||||
.categories-wrapper
|
.categories-wrapper
|
||||||
position relative
|
position relative
|
||||||
top 0
|
top 0
|
||||||
padding .9rem 1.5rem
|
padding 0.9rem 1.5rem
|
||||||
margin-bottom .9rem
|
margin-bottom 0.9rem
|
||||||
max-height 15rem
|
max-height 15rem
|
||||||
border-radius 0
|
border-radius 0
|
||||||
display none
|
display none
|
||||||
@media (max-width: $MQMobile)
|
@media (max-width $MQMobile)
|
||||||
display block
|
display block
|
||||||
.categories
|
.categories
|
||||||
max-height 12.3rem
|
max-height 12.3rem
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,16 @@
|
||||||
type="button"
|
type="button"
|
||||||
:aria-label="dropdownAriaLabel"
|
:aria-label="dropdownAriaLabel"
|
||||||
@click="toggle"
|
@click="toggle"
|
||||||
>
|
>
|
||||||
<router-link v-if="item.link" :to="item.link" class="link-title">{{ item.text }}</router-link>
|
<router-link
|
||||||
<span class="title" v-show="!item.link">{{ item.text }}</span>
|
v-if="item.link"
|
||||||
|
:to="item.link"
|
||||||
|
class="link-title"
|
||||||
|
>{{ item.text }}</router-link>
|
||||||
|
<span
|
||||||
|
class="title"
|
||||||
|
v-show="!item.link"
|
||||||
|
>{{ item.text }}</span>
|
||||||
<span
|
<span
|
||||||
class="arrow"
|
class="arrow"
|
||||||
:class="open ? 'down' : 'right'"
|
:class="open ? 'down' : 'right'"
|
||||||
|
|
@ -44,7 +51,8 @@
|
||||||
isLastItemOfArray(subItem, item.items) &&
|
isLastItemOfArray(subItem, item.items) &&
|
||||||
toggle()
|
toggle()
|
||||||
"
|
"
|
||||||
:item="childSubItem"/>
|
:item="childSubItem"
|
||||||
|
/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
@ -85,18 +93,18 @@ export default {
|
||||||
return this.item.ariaLabel || this.item.text
|
return this.item.ariaLabel || this.item.text
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount(){
|
beforeMount () {
|
||||||
this.isMQMobile = window.innerWidth < 720 ? true : false;
|
this.isMQMobile = window.innerWidth < 720 ? true : false;
|
||||||
|
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
this.isMQMobile = window.innerWidth < 720 ? true : false;
|
this.isMQMobile = window.innerWidth < 720 ? true : false;
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggle () {
|
toggle () {
|
||||||
if(this.isMQMobile){
|
if (this.isMQMobile) {
|
||||||
this.open = !this.open
|
this.open = !this.open
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
isLastItemOfArray (item, array) {
|
isLastItemOfArray (item, array) {
|
||||||
|
|
@ -158,7 +166,7 @@ export default {
|
||||||
&.router-link-active
|
&.router-link-active
|
||||||
color $accentColor
|
color $accentColor
|
||||||
&::after
|
&::after
|
||||||
content ""
|
content ''
|
||||||
width 0
|
width 0
|
||||||
height 0
|
height 0
|
||||||
border-left 5px solid $accentColor
|
border-left 5px solid $accentColor
|
||||||
|
|
@ -171,8 +179,7 @@ export default {
|
||||||
margin-top 0
|
margin-top 0
|
||||||
padding-top 0
|
padding-top 0
|
||||||
border-top 0
|
border-top 0
|
||||||
|
@media (max-width $MQMobile)
|
||||||
@media (max-width: $MQMobile)
|
|
||||||
.dropdown-wrapper
|
.dropdown-wrapper
|
||||||
&.open .dropdown-title
|
&.open .dropdown-title
|
||||||
margin-bottom 0.5rem
|
margin-bottom 0.5rem
|
||||||
|
|
@ -182,11 +189,11 @@ export default {
|
||||||
&:hover
|
&:hover
|
||||||
color $accentColor
|
color $accentColor
|
||||||
.link-title
|
.link-title
|
||||||
display none
|
display none
|
||||||
.title
|
.title
|
||||||
display inline-block!important
|
display inline-block !important
|
||||||
.nav-dropdown
|
.nav-dropdown
|
||||||
transition height .1s ease-out
|
transition height 0.1s ease-out
|
||||||
overflow hidden
|
overflow hidden
|
||||||
.dropdown-item
|
.dropdown-item
|
||||||
h4
|
h4
|
||||||
|
|
@ -199,12 +206,10 @@ export default {
|
||||||
.dropdown-subitem
|
.dropdown-subitem
|
||||||
font-size 14px
|
font-size 14px
|
||||||
padding-left 1rem
|
padding-left 1rem
|
||||||
|
@media (min-width $MQMobile)
|
||||||
@media (min-width: $MQMobile)
|
|
||||||
.dropdown-wrapper
|
.dropdown-wrapper
|
||||||
height 1.8rem
|
height 1.8rem
|
||||||
&:hover .nav-dropdown,
|
&:hover .nav-dropdown, &.open .nav-dropdown
|
||||||
&.open .nav-dropdown
|
|
||||||
// override the inline style.
|
// override the inline style.
|
||||||
display block !important
|
display block !important
|
||||||
&.open:blur
|
&.open:blur
|
||||||
|
|
@ -219,7 +224,7 @@ export default {
|
||||||
display none
|
display none
|
||||||
// Avoid height shaked by clicking
|
// Avoid height shaked by clicking
|
||||||
height auto !important
|
height auto !important
|
||||||
box-sizing border-box;
|
box-sizing border-box
|
||||||
max-height calc(100vh - 2.7rem)
|
max-height calc(100vh - 2.7rem)
|
||||||
overflow-y auto
|
overflow-y auto
|
||||||
position absolute
|
position absolute
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
@after-enter="unsetHeight"
|
@after-enter="unsetHeight"
|
||||||
@before-leave="setHeight"
|
@before-leave="setHeight"
|
||||||
>
|
>
|
||||||
<slot/>
|
<slot />
|
||||||
</transition>
|
</transition>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -29,5 +29,4 @@ export default {
|
||||||
<style lang="stylus">
|
<style lang="stylus">
|
||||||
.dropdown-enter, .dropdown-leave-to
|
.dropdown-enter, .dropdown-leave-to
|
||||||
height 0 !important
|
height 0 !important
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="icons" v-if="social && social.icons">
|
<div
|
||||||
|
class="icons"
|
||||||
|
v-if="social && social.icons"
|
||||||
|
>
|
||||||
<a
|
<a
|
||||||
:href="item.link"
|
:href="item.link"
|
||||||
:title="item.title"
|
:title="item.title"
|
||||||
|
|
@ -8,15 +11,21 @@
|
||||||
v-for="(item, index) in social.icons"
|
v-for="(item, index) in social.icons"
|
||||||
:key="index"
|
:key="index"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
></a>
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--Vdoing主题遵循MIT协议,完全开源且免费。如果您对主题的修改并不大,希望您保留主题的链接。-->
|
<!--Vdoing主题遵循MIT协议,完全开源且免费。如果您对主题的修改并不大,希望您保留主题的链接。-->
|
||||||
Theme by <a href="https://github.com/xugaoyi/vuepress-theme-vdoing" target="_blank" title="本站主题">Vdoing</a>
|
Theme by
|
||||||
|
<a
|
||||||
|
href="https://github.com/xugaoyi/vuepress-theme-vdoing"
|
||||||
|
target="_blank"
|
||||||
|
title="本站主题"
|
||||||
|
>Vdoing</a>
|
||||||
<template v-if="footer">
|
<template v-if="footer">
|
||||||
| Copyright © {{ footer.createYear }}-{{ new Date().getFullYear() }}
|
| Copyright © {{ footer.createYear }}-{{ new Date().getFullYear() }}
|
||||||
<span v-html="footer.copyrightInfo"></span>
|
<span
|
||||||
|
v-html="footer.copyrightInfo"
|
||||||
|
></span>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -24,10 +33,10 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
social() {
|
social () {
|
||||||
return this.$themeConfig.social
|
return this.$themeConfig.social
|
||||||
},
|
},
|
||||||
footer() {
|
footer () {
|
||||||
return this.$themeConfig.footer
|
return this.$themeConfig.footer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -36,14 +45,13 @@ export default {
|
||||||
|
|
||||||
<style lang='stylus'>
|
<style lang='stylus'>
|
||||||
// $mobileSidebarWidth = $sidebarWidth * 0.82
|
// $mobileSidebarWidth = $sidebarWidth * 0.82
|
||||||
|
|
||||||
.footer
|
.footer
|
||||||
padding 5rem 1.5rem 2.5rem
|
padding 5rem 1.5rem 2.5rem
|
||||||
text-align center
|
text-align center
|
||||||
color #666
|
color #666
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
font-size .85rem
|
font-size 0.85rem
|
||||||
transition all .2s ease
|
transition all 0.2s ease
|
||||||
.icons
|
.icons
|
||||||
margin-bottom 12px
|
margin-bottom 12px
|
||||||
.iconfont
|
.iconfont
|
||||||
|
|
@ -53,18 +61,14 @@ export default {
|
||||||
color inherit
|
color inherit
|
||||||
&:hover
|
&:hover
|
||||||
color $accentColor
|
color $accentColor
|
||||||
|
@media (min-width ($MQMobile + 1px))
|
||||||
@media (min-width: ($MQMobile + 1px))
|
|
||||||
.sidebar-open .footer
|
.sidebar-open .footer
|
||||||
width auto
|
width auto
|
||||||
padding-left ($sidebarWidth + 1.5rem)
|
padding-left ($sidebarWidth + 1.5rem)
|
||||||
|
|
||||||
@media (min-width 1520px)
|
@media (min-width 1520px)
|
||||||
.have-rightmenu .footer
|
.have-rightmenu .footer
|
||||||
padding-right ($rightMenuWidth + 1.5rem)
|
padding-right ($rightMenuWidth + 1.5rem)
|
||||||
|
|
||||||
.no-sidebar .footer
|
.no-sidebar .footer
|
||||||
width auto
|
width auto
|
||||||
padding-left 1.5rem
|
padding-left 1.5rem
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -377,12 +377,11 @@ export default {
|
||||||
font-size 3.2rem
|
font-size 3.2rem
|
||||||
.description, .action
|
.description, .action
|
||||||
margin 1.5rem auto
|
margin 1.5rem auto
|
||||||
|
|
||||||
.description
|
.description
|
||||||
max-width 40rem
|
max-width 40rem
|
||||||
font-size 1.1rem
|
font-size 1.1rem
|
||||||
line-height 1.3
|
line-height 1.3
|
||||||
opacity .9
|
opacity 0.9
|
||||||
.action-button
|
.action-button
|
||||||
display inline-block
|
display inline-block
|
||||||
font-size 1.2rem
|
font-size 1.2rem
|
||||||
|
|
@ -424,17 +423,15 @@ export default {
|
||||||
padding-bottom 0
|
padding-bottom 0
|
||||||
p
|
p
|
||||||
opacity 0.8
|
opacity 0.8
|
||||||
padding 0 .8rem
|
padding 0 0.8rem
|
||||||
.feature:hover
|
.feature:hover
|
||||||
.feature-img
|
.feature-img
|
||||||
animation-play-state: running
|
animation-play-state running
|
||||||
h2,p
|
h2, p
|
||||||
color $accentColor
|
color $accentColor
|
||||||
|
|
||||||
|
|
||||||
// 移动端滑动图标
|
// 移动端滑动图标
|
||||||
.slide-banner
|
.slide-banner
|
||||||
margin-top: 2rem;
|
margin-top 2rem
|
||||||
.banner-wrapper
|
.banner-wrapper
|
||||||
position relative
|
position relative
|
||||||
.slide-banner-scroll
|
.slide-banner-scroll
|
||||||
|
|
@ -460,7 +457,7 @@ export default {
|
||||||
padding-bottom 0
|
padding-bottom 0
|
||||||
p
|
p
|
||||||
opacity 0.8
|
opacity 0.8
|
||||||
padding 0 .8rem
|
padding 0 0.8rem
|
||||||
.docs-wrapper
|
.docs-wrapper
|
||||||
position absolute
|
position absolute
|
||||||
bottom 25px
|
bottom 25px
|
||||||
|
|
@ -473,22 +470,20 @@ export default {
|
||||||
height 8px
|
height 8px
|
||||||
border-radius 50%
|
border-radius 50%
|
||||||
background var(--textColor)
|
background var(--textColor)
|
||||||
opacity .9
|
opacity 0.9
|
||||||
&.active
|
&.active
|
||||||
opacity .5
|
opacity 0.5
|
||||||
|
|
||||||
// 分页不在第一页时,隐藏banner栏
|
// 分页不在第一页时,隐藏banner栏
|
||||||
.main-wrapper
|
.main-wrapper
|
||||||
margin-top 2rem
|
margin-top 2rem
|
||||||
.banner.hide-banner
|
.banner.hide-banner
|
||||||
display none
|
display none
|
||||||
& + .main-wrapper
|
& + .main-wrapper
|
||||||
margin-top ($navbarHeight + .9rem)
|
margin-top ($navbarHeight + 0.9rem)
|
||||||
|
|
||||||
.main-wrapper
|
.main-wrapper
|
||||||
.main-left
|
.main-left
|
||||||
.card-box
|
.card-box
|
||||||
margin-bottom .9rem
|
margin-bottom 0.9rem
|
||||||
.pagination
|
.pagination
|
||||||
margin-bottom 4rem
|
margin-bottom 4rem
|
||||||
.theme-vdoing-content
|
.theme-vdoing-content
|
||||||
|
|
@ -498,13 +493,13 @@ export default {
|
||||||
padding-top 2rem
|
padding-top 2rem
|
||||||
&>:last-child
|
&>:last-child
|
||||||
padding-bottom 2rem
|
padding-bottom 2rem
|
||||||
|
|
||||||
@keyframes heart
|
@keyframes heart
|
||||||
from{transform:translate(0,0)}
|
from
|
||||||
to{transform:translate(0,8px)}
|
transform translate(0, 0)
|
||||||
|
to
|
||||||
|
transform translate(0, 8px)
|
||||||
// 1025px以下
|
// 1025px以下
|
||||||
@media (max-width: 1025px)
|
@media (max-width 1025px)
|
||||||
.home-wrapper
|
.home-wrapper
|
||||||
.banner
|
.banner
|
||||||
.banner-conent
|
.banner-conent
|
||||||
|
|
@ -520,38 +515,33 @@ export default {
|
||||||
.feature-img
|
.feature-img
|
||||||
width 9rem
|
width 9rem
|
||||||
height 9rem
|
height 9rem
|
||||||
|
|
||||||
// 719px以下
|
// 719px以下
|
||||||
@media (max-width: $MQMobile)
|
@media (max-width $MQMobile)
|
||||||
.home-wrapper
|
.home-wrapper
|
||||||
.banner
|
.banner
|
||||||
.banner-conent
|
.banner-conent
|
||||||
.features
|
.features
|
||||||
display none!important
|
display none !important
|
||||||
|
|
||||||
// 419px以下
|
// 419px以下
|
||||||
@media (max-width: $MQMobileNarrow)
|
@media (max-width $MQMobileNarrow)
|
||||||
.home-wrapper
|
.home-wrapper
|
||||||
.banner-conent
|
.banner-conent
|
||||||
padding-left 1.5rem
|
padding-left 1.5rem
|
||||||
padding-right 1.5rem
|
padding-right 1.5rem
|
||||||
|
|
||||||
.hero
|
.hero
|
||||||
img
|
img
|
||||||
max-height 210px
|
max-height 210px
|
||||||
margin 2rem auto 1.2rem
|
margin 2rem auto 1.2rem
|
||||||
h1
|
h1
|
||||||
font-size: 2rem
|
font-size 2rem
|
||||||
h1, .description, .action
|
h1, .description, .action
|
||||||
margin: 1.2rem auto
|
margin 1.2rem auto
|
||||||
|
|
||||||
.description
|
.description
|
||||||
font-size: 1.2rem
|
font-size 1.2rem
|
||||||
|
|
||||||
.action-button
|
.action-button
|
||||||
font-size 1rem
|
font-size 1rem
|
||||||
padding 0.6rem 1.2rem
|
padding 0.6rem 1.2rem
|
||||||
.feature
|
.feature
|
||||||
h2
|
h2
|
||||||
font-size: 1.25rem
|
font-size 1.25rem
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
.main-wrapper
|
.main-wrapper
|
||||||
margin 1.5rem auto 0 auto
|
margin 1.5rem auto 0 auto
|
||||||
max-width $homePageWidth
|
max-width $homePageWidth
|
||||||
padding 0 .9rem
|
padding 0 0.9rem
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
position relative
|
position relative
|
||||||
display flex
|
display flex
|
||||||
|
|
@ -22,23 +22,22 @@
|
||||||
width 72%
|
width 72%
|
||||||
.theme-vdoing-content.card-box
|
.theme-vdoing-content.card-box
|
||||||
padding 1rem 1.5rem
|
padding 1rem 1.5rem
|
||||||
margin-bottom .9rem
|
margin-bottom 0.9rem
|
||||||
.home-content
|
.home-content
|
||||||
padding 1rem 1.5rem 0
|
padding 1rem 1.5rem 0
|
||||||
.main-right
|
.main-right
|
||||||
>*
|
>*
|
||||||
width 265px
|
width 265px
|
||||||
box-sizing border-box
|
box-sizing border-box
|
||||||
@media (max-width 900px)
|
@media (max-width 900px)
|
||||||
width 235px
|
width 235px
|
||||||
.card-box
|
.card-box
|
||||||
margin 0 0 .9rem .9rem
|
margin 0 0 0.9rem 0.9rem
|
||||||
padding .95rem
|
padding 0.95rem
|
||||||
|
|
||||||
// 719px以下
|
// 719px以下
|
||||||
@media (max-width: $MQMobile)
|
@media (max-width $MQMobile)
|
||||||
.main-wrapper
|
.main-wrapper
|
||||||
margin .9rem 0
|
margin 0.9rem 0
|
||||||
padding 0
|
padding 0
|
||||||
display block
|
display block
|
||||||
.main-left
|
.main-left
|
||||||
|
|
@ -53,7 +52,7 @@
|
||||||
.blogger-wrapper
|
.blogger-wrapper
|
||||||
display none
|
display none
|
||||||
.card-box
|
.card-box
|
||||||
margin 0 0 .9rem 0
|
margin 0 0 0.9rem 0
|
||||||
border-radius 0
|
border-radius 0
|
||||||
width 100%
|
width 100%
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
:rel="isMailto(link) || isTel(link) ? null : 'noopener noreferrer'"
|
:rel="isMailto(link) || isTel(link) ? null : 'noopener noreferrer'"
|
||||||
>
|
>
|
||||||
{{ item.text }}
|
{{ item.text }}
|
||||||
<OutboundLink/>
|
<OutboundLink />
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
{{ repoLabel }}
|
{{ repoLabel }}
|
||||||
<OutboundLink/>
|
<OutboundLink />
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -134,19 +134,16 @@ export default {
|
||||||
margin-left 0
|
margin-left 0
|
||||||
.repo-link
|
.repo-link
|
||||||
margin-left 1.5rem
|
margin-left 1.5rem
|
||||||
|
|
||||||
// 959
|
// 959
|
||||||
@media (max-width: $MQNarrow)
|
@media (max-width $MQNarrow)
|
||||||
.nav-links
|
.nav-links
|
||||||
.nav-item
|
.nav-item
|
||||||
margin-left 1.2rem
|
margin-left 1.2rem
|
||||||
|
@media (max-width $MQMobile)
|
||||||
@media (max-width: $MQMobile)
|
|
||||||
.nav-links
|
.nav-links
|
||||||
.nav-item, .repo-link
|
.nav-item, .repo-link
|
||||||
margin-left 0
|
margin-left 0
|
||||||
|
@media (min-width $MQMobile)
|
||||||
@media (min-width: $MQMobile)
|
|
||||||
.nav-links a
|
.nav-links a
|
||||||
&:hover, &.router-link-active
|
&:hover, &.router-link-active
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<header class="navbar blur">
|
<header class="navbar blur">
|
||||||
<SidebarButton @toggle-sidebar="$emit('toggle-sidebar')"/>
|
<SidebarButton @toggle-sidebar="$emit('toggle-sidebar')" />
|
||||||
|
|
||||||
<router-link
|
<router-link
|
||||||
:to="$localePath"
|
:to="$localePath"
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
v-if="$site.themeConfig.logo"
|
v-if="$site.themeConfig.logo"
|
||||||
:src="$withBase($site.themeConfig.logo)"
|
:src="$withBase($site.themeConfig.logo)"
|
||||||
:alt="$siteTitle"
|
:alt="$siteTitle"
|
||||||
>
|
/>
|
||||||
<span
|
<span
|
||||||
ref="siteName"
|
ref="siteName"
|
||||||
class="site-name"
|
class="site-name"
|
||||||
|
|
@ -30,8 +30,10 @@
|
||||||
v-if="isAlgoliaSearch"
|
v-if="isAlgoliaSearch"
|
||||||
:options="algolia"
|
:options="algolia"
|
||||||
/>
|
/>
|
||||||
<SearchBox v-else-if="$site.themeConfig.search !== false && $page.frontmatter.search !== false"/>
|
<SearchBox
|
||||||
<NavLinks class="can-hide"/>
|
v-else-if="$site.themeConfig.search !== false && $page.frontmatter.search !== false"
|
||||||
|
/>
|
||||||
|
<NavLinks class="can-hide" />
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -88,7 +90,6 @@ function css (el, property) {
|
||||||
<style lang="stylus">
|
<style lang="stylus">
|
||||||
$navbar-vertical-padding = 0.7rem
|
$navbar-vertical-padding = 0.7rem
|
||||||
$navbar-horizontal-padding = 1.5rem
|
$navbar-horizontal-padding = 1.5rem
|
||||||
|
|
||||||
.navbar
|
.navbar
|
||||||
padding $navbar-vertical-padding $navbar-horizontal-padding
|
padding $navbar-vertical-padding $navbar-horizontal-padding
|
||||||
line-height $navbarHeight - 1.4rem
|
line-height $navbarHeight - 1.4rem
|
||||||
|
|
@ -115,20 +116,17 @@ $navbar-horizontal-padding = 1.5rem
|
||||||
top $navbar-vertical-padding
|
top $navbar-vertical-padding
|
||||||
display flex
|
display flex
|
||||||
.search-box
|
.search-box
|
||||||
flex: 0 0 auto
|
flex 0 0 auto
|
||||||
vertical-align top
|
vertical-align top
|
||||||
|
|
||||||
.hide-navbar
|
.hide-navbar
|
||||||
.navbar
|
.navbar
|
||||||
transform translateY(-100%)
|
transform translateY(-100%)
|
||||||
|
|
||||||
// 959
|
// 959
|
||||||
@media (max-width: $MQNarrow)
|
@media (max-width $MQNarrow)
|
||||||
.navbar
|
.navbar
|
||||||
.site-name
|
.site-name
|
||||||
display none
|
display none
|
||||||
|
@media (max-width $MQMobile)
|
||||||
@media (max-width: $MQMobile)
|
|
||||||
.navbar
|
.navbar
|
||||||
padding-left 4rem
|
padding-left 4rem
|
||||||
.can-hide
|
.can-hide
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,26 @@
|
||||||
<div>
|
<div>
|
||||||
<main class="page">
|
<main class="page">
|
||||||
<slot name="top" />
|
<slot name="top" />
|
||||||
|
|
||||||
<div :class="`theme-vdoing-wrapper ${bgStyle}`" >
|
<div :class="`theme-vdoing-wrapper ${bgStyle}`">
|
||||||
|
|
||||||
<ArticleInfo v-if="isArticle()" />
|
<ArticleInfo v-if="isArticle()" />
|
||||||
<component class="theme-vdoing-content" v-if="pageComponent" :is="pageComponent" />
|
<component
|
||||||
|
class="theme-vdoing-content"
|
||||||
|
v-if="pageComponent"
|
||||||
|
:is="pageComponent"
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<RightMenu v-if="showRightMenu"/>
|
<RightMenu v-if="showRightMenu" />
|
||||||
<h1 v-if="showTitle">
|
<h1 v-if="showTitle">
|
||||||
<img :src="currentBadge" v-if="$themeConfig.titleBadge === false ? false : true">
|
<img
|
||||||
|
:src="currentBadge"
|
||||||
|
v-if="$themeConfig.titleBadge === false ? false : true"
|
||||||
|
/>
|
||||||
{{this.$page.title}}
|
{{this.$page.title}}
|
||||||
</h1>
|
</h1>
|
||||||
<Content class="theme-vdoing-content" />
|
<Content class="theme-vdoing-content" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<PageEdit />
|
<PageEdit />
|
||||||
<PageNav v-bind="{ sidebarItems }" />
|
<PageNav v-bind="{ sidebarItems }" />
|
||||||
|
|
@ -30,7 +35,6 @@
|
||||||
|
|
||||||
<slot name="bottom" />
|
<slot name="bottom" />
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -46,28 +50,28 @@ import TitleBadgeMixin from '../mixins/titleBadge'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [TitleBadgeMixin],
|
mixins: [TitleBadgeMixin],
|
||||||
data() {
|
data () {
|
||||||
return {
|
return {
|
||||||
updateBarConfig: null
|
updateBarConfig: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: ['sidebarItems'],
|
props: ['sidebarItems'],
|
||||||
components: { PageEdit, PageNav, ArticleInfo, Catalogue, UpdateArticle, RightMenu},
|
components: { PageEdit, PageNav, ArticleInfo, Catalogue, UpdateArticle, RightMenu },
|
||||||
created() {
|
created () {
|
||||||
this.updateBarConfig = this.$themeConfig.updateBar
|
this.updateBarConfig = this.$themeConfig.updateBar
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
bgStyle(){
|
bgStyle () {
|
||||||
const { contentBgStyle } = this.$themeConfig
|
const { contentBgStyle } = this.$themeConfig
|
||||||
return contentBgStyle ? 'bg-style-' + contentBgStyle : ''
|
return contentBgStyle ? 'bg-style-' + contentBgStyle : ''
|
||||||
},
|
},
|
||||||
isShowUpdateBar() {
|
isShowUpdateBar () {
|
||||||
return this.updateBarConfig && this.updateBarConfig.showToArticle === false ? false : true
|
return this.updateBarConfig && this.updateBarConfig.showToArticle === false ? false : true
|
||||||
},
|
},
|
||||||
showTitle() {
|
showTitle () {
|
||||||
return !this.$frontmatter.pageComponent
|
return !this.$frontmatter.pageComponent
|
||||||
},
|
},
|
||||||
showRightMenu(){
|
showRightMenu () {
|
||||||
return this.$page.headers && (this.$frontmatter && this.$frontmatter.sidebar && this.$frontmatter.sidebar !== false) !== false
|
return this.$page.headers && (this.$frontmatter && this.$frontmatter.sidebar && this.$frontmatter.sidebar !== false) !== false
|
||||||
},
|
},
|
||||||
pageComponent () {
|
pageComponent () {
|
||||||
|
|
@ -75,7 +79,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
isArticle() {
|
isArticle () {
|
||||||
return this.$frontmatter.article !== false
|
return this.$frontmatter.article !== false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -88,13 +92,12 @@ export default {
|
||||||
.page
|
.page
|
||||||
padding-bottom 2rem
|
padding-bottom 2rem
|
||||||
display block
|
display block
|
||||||
@media (max-width $MQMobile)
|
@media (max-width $MQMobile)
|
||||||
padding-top ($navbarHeight)
|
padding-top $navbarHeight
|
||||||
@media (min-width $MQMobile)
|
@media (min-width $MQMobile)
|
||||||
padding-top ($navbarHeight + 1.5rem)
|
padding-top ($navbarHeight + 1.5rem)
|
||||||
>*
|
>*
|
||||||
@extend $vdoing-wrapper
|
@extend $vdoing-wrapper
|
||||||
|
|
||||||
.theme-vdoing-wrapper
|
.theme-vdoing-wrapper
|
||||||
.content-wrapper
|
.content-wrapper
|
||||||
position relative
|
position relative
|
||||||
|
|
@ -102,48 +105,42 @@ export default {
|
||||||
margin-bottom -0.2rem
|
margin-bottom -0.2rem
|
||||||
max-width 2.2rem
|
max-width 2.2rem
|
||||||
max-height 2.2rem
|
max-height 2.2rem
|
||||||
|
|
||||||
|
|
||||||
.theme-vdoing-wrapper
|
.theme-vdoing-wrapper
|
||||||
--linesColor: rgba(50, 0, 0, 0.05)
|
--linesColor rgba(50, 0, 0, 0.05)
|
||||||
&.bg-style-1 // 方格
|
&.bg-style-1 // 方格
|
||||||
background-image: linear-gradient(90deg, var(--linesColor) 3%, transparent 3%), linear-gradient(0deg, var(--linesColor) 3%, transparent 3%)
|
background-image linear-gradient(90deg, var(--linesColor) 3%, transparent 3%), linear-gradient(0deg, var(--linesColor) 3%, transparent 3%)
|
||||||
background-position: center center
|
background-position center center
|
||||||
background-size: 20px 20px
|
background-size 20px 20px
|
||||||
&.bg-style-2 // 横线
|
&.bg-style-2 // 横线
|
||||||
background-image: repeating-linear-gradient(0, var(--linesColor) 0, var(--linesColor) 1px, transparent 0, transparent 50%);
|
background-image repeating-linear-gradient(0, var(--linesColor) 0, var(--linesColor) 1px, transparent 0, transparent 50%)
|
||||||
background-size: 30px 30px
|
background-size 30px 30px
|
||||||
&.bg-style-3 // 竖线
|
&.bg-style-3 // 竖线
|
||||||
background-image: repeating-linear-gradient(90deg, var(--linesColor) 0, var(--linesColor) 1px, transparent 0, transparent 50%);
|
background-image repeating-linear-gradient(90deg, var(--linesColor) 0, var(--linesColor) 1px, transparent 0, transparent 50%)
|
||||||
background-size: 30px 30px
|
background-size 30px 30px
|
||||||
&.bg-style-4 // 左斜线
|
&.bg-style-4 // 左斜线
|
||||||
background-image: repeating-linear-gradient(-45deg, var(--linesColor) 0, var(--linesColor) 1px, transparent 0, transparent 50%);
|
background-image repeating-linear-gradient(-45deg, var(--linesColor) 0, var(--linesColor) 1px, transparent 0, transparent 50%)
|
||||||
background-size: 20px 20px
|
background-size 20px 20px
|
||||||
&.bg-style-5 // 右斜线
|
&.bg-style-5 // 右斜线
|
||||||
background-image: repeating-linear-gradient(45deg, var(--linesColor) 0, var(--linesColor) 1px, transparent 0, transparent 50%);
|
background-image repeating-linear-gradient(45deg, var(--linesColor) 0, var(--linesColor) 1px, transparent 0, transparent 50%)
|
||||||
background-size: 20px 20px
|
background-size 20px 20px
|
||||||
&.bg-style-6 // 点状
|
&.bg-style-6 // 点状
|
||||||
background-image: radial-gradient(var(--linesColor) 1px, transparent 1px);
|
background-image radial-gradient(var(--linesColor) 1px, transparent 1px)
|
||||||
background-size: 10px 10px
|
background-size 10px 10px
|
||||||
|
|
||||||
// 背景纹适应深色模式
|
// 背景纹适应深色模式
|
||||||
.theme-mode-dark
|
.theme-mode-dark
|
||||||
.theme-vdoing-wrapper
|
.theme-vdoing-wrapper
|
||||||
--linesColor: rgba(125,125,125, 0.05)
|
--linesColor rgba(125, 125, 125, 0.05)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 右侧菜单的自适应
|
* 右侧菜单的自适应
|
||||||
*/
|
*/
|
||||||
@media (min-width: 720px) and (max-width: 1279px)
|
@media (min-width 720px) and (max-width 1279px)
|
||||||
.have-rightmenu
|
.have-rightmenu
|
||||||
.page
|
.page
|
||||||
padding-right .8rem!important
|
padding-right 0.8rem !important
|
||||||
|
@media (max-width 1279px)
|
||||||
@media (max-width: 1279px)
|
|
||||||
.right-menu-wrapper
|
.right-menu-wrapper
|
||||||
display none
|
display none
|
||||||
@media (min-width: 1280px)
|
@media (min-width 1280px)
|
||||||
.sidebar .sidebar-sub-headers
|
.sidebar .sidebar-sub-headers
|
||||||
display none
|
display none
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,33 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="page-edit">
|
<div class="page-edit">
|
||||||
<div class="edit-link" v-if="editLink">
|
<div
|
||||||
<a :href="editLink" target="_blank" rel="noopener noreferrer">{{ editLinkText }}</a>
|
class="edit-link"
|
||||||
|
v-if="editLink"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
:href="editLink"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>{{ editLinkText }}</a>
|
||||||
<OutboundLink />
|
<OutboundLink />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tags" v-if="$themeConfig.tag !== false && tags && tags[0]">
|
<div
|
||||||
<router-link :to="`/tags/?tag=${encodeUrl(item)}`" v-for="(item, index) in tags" :key="index" title="标签">
|
class="tags"
|
||||||
#{{item}}
|
v-if="$themeConfig.tag !== false && tags && tags[0]"
|
||||||
</router-link>
|
>
|
||||||
|
<router-link
|
||||||
|
:to="`/tags/?tag=${encodeURIComponent(item)}`"
|
||||||
|
v-for="(item, index) in tags"
|
||||||
|
:key="index"
|
||||||
|
title="标签"
|
||||||
|
>#{{item}}</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="last-updated" v-if="lastUpdated">
|
<div
|
||||||
|
class="last-updated"
|
||||||
|
v-if="lastUpdated"
|
||||||
|
>
|
||||||
<span class="prefix">{{ lastUpdatedText }}:</span>
|
<span class="prefix">{{ lastUpdatedText }}:</span>
|
||||||
<span class="time">{{ lastUpdated }}</span>
|
<span class="time">{{ lastUpdated }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -20,16 +36,14 @@
|
||||||
<script>
|
<script>
|
||||||
import isNil from 'lodash/isNil'
|
import isNil from 'lodash/isNil'
|
||||||
import { endingSlashRE, outboundRE } from '../util'
|
import { endingSlashRE, outboundRE } from '../util'
|
||||||
import encodeMixin from '../mixins/encodeUrl'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [encodeMixin],
|
|
||||||
name: 'PageEdit',
|
name: 'PageEdit',
|
||||||
computed: {
|
computed: {
|
||||||
tags() {
|
tags () {
|
||||||
return this.$frontmatter.tags
|
return this.$frontmatter.tags
|
||||||
},
|
},
|
||||||
|
|
||||||
lastUpdated () {
|
lastUpdated () {
|
||||||
return this.$page.lastUpdated
|
return this.$page.lastUpdated
|
||||||
},
|
},
|
||||||
|
|
@ -114,43 +128,39 @@ export default {
|
||||||
padding-top 1rem
|
padding-top 1rem
|
||||||
padding-bottom 1rem
|
padding-bottom 1rem
|
||||||
overflow auto
|
overflow auto
|
||||||
|
|
||||||
.edit-link
|
.edit-link
|
||||||
display inline-block
|
display inline-block
|
||||||
float left
|
float left
|
||||||
margin 0 2rem .5rem 0
|
margin 0 2rem 0.5rem 0
|
||||||
a
|
a
|
||||||
margin-right 0.25rem
|
margin-right 0.25rem
|
||||||
.tags
|
.tags
|
||||||
float left
|
float left
|
||||||
a
|
a
|
||||||
margin 0 .8rem .5rem 0
|
margin 0 0.8rem 0.5rem 0
|
||||||
display inline-block
|
display inline-block
|
||||||
color var(--textLightenColor)
|
color var(--textLightenColor)
|
||||||
padding 0.2rem 0.7rem
|
padding 0.2rem 0.7rem
|
||||||
font-size 0.9em
|
font-size 0.9em
|
||||||
background-color rgba(128,128,128,0.08)
|
background-color rgba(128, 128, 128, 0.08)
|
||||||
border-radius 3px
|
border-radius 3px
|
||||||
opacity .8
|
opacity 0.8
|
||||||
|
|
||||||
.last-updated
|
.last-updated
|
||||||
float right
|
float right
|
||||||
font-size 0.9em
|
font-size 0.9em
|
||||||
.prefix
|
.prefix
|
||||||
font-weight 500
|
font-weight 500
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
opacity .8
|
opacity 0.8
|
||||||
.time
|
.time
|
||||||
font-weight 400
|
font-weight 400
|
||||||
color #aaa
|
color #aaa
|
||||||
|
@media (max-width $MQMobile)
|
||||||
@media (max-width: $MQMobile)
|
|
||||||
.page-edit
|
.page-edit
|
||||||
.edit-link,.tags
|
.edit-link, .tags
|
||||||
margin-bottom .5rem
|
margin-bottom 0.5rem
|
||||||
.last-updated
|
.last-updated
|
||||||
width 100%
|
width 100%
|
||||||
font-size 0.8em
|
font-size 0.8em
|
||||||
text-align left
|
text-align left
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="page-nav-wapper">
|
<div class="page-nav-wapper">
|
||||||
<!-- 页面中间左右翻页 -->
|
<!-- 页面中间左右翻页 -->
|
||||||
<div class="page-nav-centre-wrap" v-if="$themeConfig.pageButton !== false && (prev || next)">
|
<div
|
||||||
|
class="page-nav-centre-wrap"
|
||||||
|
v-if="$themeConfig.pageButton !== false && (prev || next)"
|
||||||
|
>
|
||||||
<router-link
|
<router-link
|
||||||
class="page-nav-centre page-nav-centre-prev"
|
class="page-nav-centre page-nav-centre-prev"
|
||||||
v-if="prev"
|
v-if="prev"
|
||||||
|
|
@ -9,12 +12,9 @@
|
||||||
@mouseenter.native="showTooltip($event)"
|
@mouseenter.native="showTooltip($event)"
|
||||||
@mousemove.native="showTooltip($event)"
|
@mousemove.native="showTooltip($event)"
|
||||||
>
|
>
|
||||||
<div class="tooltip">
|
<div class="tooltip">{{ prev.title || prev.path }}</div>
|
||||||
{{ prev.title || prev.path }}
|
|
||||||
</div>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
|
|
||||||
<router-link
|
<router-link
|
||||||
class="page-nav-centre page-nav-centre-next"
|
class="page-nav-centre page-nav-centre-next"
|
||||||
v-if="next"
|
v-if="next"
|
||||||
|
|
@ -22,23 +22,36 @@
|
||||||
@mouseenter.native="showTooltip($event)"
|
@mouseenter.native="showTooltip($event)"
|
||||||
@mousemove.native="showTooltip($event)"
|
@mousemove.native="showTooltip($event)"
|
||||||
>
|
>
|
||||||
<div class="tooltip">
|
<div class="tooltip">{{ next.title || next.path }}</div>
|
||||||
{{ next.title || next.path }}
|
|
||||||
</div>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 底部翻页按钮 -->
|
<!-- 底部翻页按钮 -->
|
||||||
<div class="page-nav" v-if="prev || next">
|
<div
|
||||||
|
class="page-nav"
|
||||||
|
v-if="prev || next"
|
||||||
|
>
|
||||||
<p class="inner">
|
<p class="inner">
|
||||||
<span v-if="prev" class="prev">
|
<span
|
||||||
|
v-if="prev"
|
||||||
|
class="prev"
|
||||||
|
>
|
||||||
←
|
←
|
||||||
<router-link v-if="prev" class="prev" :to="prev.path">{{ prev.title || prev.path }}</router-link>
|
<router-link
|
||||||
|
v-if="prev"
|
||||||
|
class="prev"
|
||||||
|
:to="prev.path"
|
||||||
|
>{{ prev.title || prev.path }}</router-link>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span v-if="next" class="next">
|
<span
|
||||||
<router-link v-if="next" :to="next.path">{{ next.title || next.path }}</router-link>
|
v-if="next"
|
||||||
→
|
class="next"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
v-if="next"
|
||||||
|
:to="next.path"
|
||||||
|
>{{ next.title || next.path }}</router-link>→
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -62,7 +75,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showTooltip(e) {
|
showTooltip (e) {
|
||||||
|
|
||||||
const clientW = document.body.clientWidth
|
const clientW = document.body.clientWidth
|
||||||
const X = e.clientX
|
const X = e.clientX
|
||||||
|
|
@ -72,7 +85,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
const tooltipEleStyle = tooltipEle.style
|
const tooltipEleStyle = tooltipEle.style
|
||||||
if (X < clientW/2) {
|
if (X < clientW / 2) {
|
||||||
tooltipEleStyle.right = null
|
tooltipEleStyle.right = null
|
||||||
tooltipEleStyle.left = X + 10 + 'px'
|
tooltipEleStyle.left = X + 10 + 'px'
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -165,8 +178,6 @@ function flatten (items, res) {
|
||||||
overflow auto // clear float
|
overflow auto // clear float
|
||||||
.next
|
.next
|
||||||
float right
|
float right
|
||||||
|
|
||||||
|
|
||||||
.page-nav-centre-wrap
|
.page-nav-centre-wrap
|
||||||
.page-nav-centre
|
.page-nav-centre
|
||||||
position fixed
|
position fixed
|
||||||
|
|
@ -175,21 +186,21 @@ function flatten (items, res) {
|
||||||
height 70px
|
height 70px
|
||||||
margin-top -35px
|
margin-top -35px
|
||||||
outline 0
|
outline 0
|
||||||
transition all .2s
|
transition all 0.2s
|
||||||
border-radius 3px
|
border-radius 3px
|
||||||
opacity .55
|
opacity 0.55
|
||||||
z-index 99
|
z-index 99
|
||||||
@media (max-width: 1340px)
|
@media (max-width 1340px)
|
||||||
width 50px
|
width 50px
|
||||||
@media (max-width: 960px)
|
@media (max-width 960px)
|
||||||
display none
|
display none
|
||||||
&:hover
|
&:hover
|
||||||
background rgba(153, 153, 153, .15)
|
background rgba(153, 153, 153, 0.15)
|
||||||
opacity 1
|
opacity 1
|
||||||
.tooltip
|
.tooltip
|
||||||
display block
|
display block
|
||||||
&:before
|
&:before
|
||||||
content: ""
|
content ''
|
||||||
display block
|
display block
|
||||||
width 10px
|
width 10px
|
||||||
height 10px
|
height 10px
|
||||||
|
|
@ -203,7 +214,7 @@ function flatten (items, res) {
|
||||||
margin auto
|
margin auto
|
||||||
.tooltip
|
.tooltip
|
||||||
display none
|
display none
|
||||||
background rgba(0, 0, 0, .5)
|
background rgba(0, 0, 0, 0.5)
|
||||||
color #fff
|
color #fff
|
||||||
padding 4px 8px
|
padding 4px 8px
|
||||||
font-size 13px
|
font-size 13px
|
||||||
|
|
@ -211,19 +222,16 @@ function flatten (items, res) {
|
||||||
position fixed
|
position fixed
|
||||||
max-width 200px
|
max-width 200px
|
||||||
z-index 99
|
z-index 99
|
||||||
|
|
||||||
.page-nav-centre-prev
|
.page-nav-centre-prev
|
||||||
left 0
|
left 0
|
||||||
&:before
|
&:before
|
||||||
transform rotate(-135deg)
|
transform rotate(-135deg)
|
||||||
.page-nav-centre-next
|
.page-nav-centre-next
|
||||||
right: 0
|
right 0
|
||||||
&:before
|
&:before
|
||||||
transform rotate(45deg)
|
transform rotate(45deg)
|
||||||
|
|
||||||
.sidebar-open .page-nav-centre-wrap .page-nav-centre-prev
|
.sidebar-open .page-nav-centre-wrap .page-nav-centre-prev
|
||||||
left $sidebarWidth
|
left $sidebarWidth
|
||||||
.no-sidebar .page-nav-centre-wrap .page-nav-centre-prev
|
.no-sidebar .page-nav-centre-wrap .page-nav-centre-prev
|
||||||
left 0
|
left 0
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,80 +1,86 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="pagination">
|
<div class="pagination">
|
||||||
<span class="card-box prev iconfont icon-jiantou-zuo"
|
<span
|
||||||
:class="{disabled: currentPage === 1}"
|
class="card-box prev iconfont icon-jiantou-zuo"
|
||||||
@click="goPrex()"
|
:class="{disabled: currentPage === 1}"
|
||||||
|
@click="goPrex()"
|
||||||
>
|
>
|
||||||
<p>上一页</p>
|
<p>上一页</p>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<!-- 分页在5页及以下时 -->
|
<!-- 分页在5页及以下时 -->
|
||||||
<div class="pagination-list" v-if="pages <= 5">
|
<div
|
||||||
<span class="card-box"
|
class="pagination-list"
|
||||||
v-for="item in pages"
|
v-if="pages <= 5"
|
||||||
:key="item"
|
>
|
||||||
:class="{active: currentPage === item}"
|
<span
|
||||||
@click="goIndex(item)"
|
class="card-box"
|
||||||
>
|
v-for="item in pages"
|
||||||
{{item}}
|
:key="item"
|
||||||
</span>
|
:class="{active: currentPage === item}"
|
||||||
|
@click="goIndex(item)"
|
||||||
|
>{{item}}</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- 分页在5页以上 -->
|
<!-- 分页在5页以上 -->
|
||||||
<div class="pagination-list" v-else>
|
<div
|
||||||
|
class="pagination-list"
|
||||||
|
v-else
|
||||||
|
>
|
||||||
<!-- 一号位 -->
|
<!-- 一号位 -->
|
||||||
<span class="card-box"
|
<span
|
||||||
:class="{active: currentPage === 1}"
|
class="card-box"
|
||||||
@click="goIndex(1)"
|
:class="{active: currentPage === 1}"
|
||||||
>
|
@click="goIndex(1)"
|
||||||
1
|
>1</span>
|
||||||
</span>
|
|
||||||
|
|
||||||
<!-- 二号位 -->
|
<!-- 二号位 -->
|
||||||
<span class="ellipsis ell-two"
|
<span
|
||||||
v-show="currentPage > 3"
|
class="ellipsis ell-two"
|
||||||
@click="goIndex(currentPage - 2)"
|
v-show="currentPage > 3"
|
||||||
title="上两页"
|
@click="goIndex(currentPage - 2)"
|
||||||
|
title="上两页"
|
||||||
/>
|
/>
|
||||||
<!--这里没有使用v-if的原因是因为部署版本在当前页大于3时刷新页面出现了一些bug-->
|
<!--这里没有使用v-if的原因是因为部署版本在当前页大于3时刷新页面出现了一些bug-->
|
||||||
<span class="card-box"
|
<span
|
||||||
v-show="currentPage <= 3"
|
class="card-box"
|
||||||
:class="{active: currentPage === 2}"
|
v-show="currentPage <= 3"
|
||||||
@click="goIndex(2)"
|
:class="{active: currentPage === 2}"
|
||||||
|
@click="goIndex(2)"
|
||||||
>2</span>
|
>2</span>
|
||||||
|
|
||||||
<!-- 三号位 -->
|
<!-- 三号位 -->
|
||||||
<span class="card-box"
|
<span
|
||||||
:class="{active: currentPage >= 3 && currentPage <= (pages - 2)}"
|
class="card-box"
|
||||||
@click="goIndex(threeNum())"
|
:class="{active: currentPage >= 3 && currentPage <= (pages - 2)}"
|
||||||
>
|
@click="goIndex(threeNum())"
|
||||||
{{ threeNum() }}
|
>{{ threeNum() }}</span>
|
||||||
</span>
|
|
||||||
|
|
||||||
<!-- 四号位 -->
|
<!-- 四号位 -->
|
||||||
<span class="ellipsis ell-four"
|
<span
|
||||||
v-show="currentPage < (pages - 2)"
|
class="ellipsis ell-four"
|
||||||
@click="goIndex(currentPage + 2)"
|
v-show="currentPage < (pages - 2)"
|
||||||
title="下两页"
|
@click="goIndex(currentPage + 2)"
|
||||||
|
title="下两页"
|
||||||
/>
|
/>
|
||||||
<span class="card-box"
|
<span
|
||||||
v-show="currentPage >= (pages - 2)"
|
class="card-box"
|
||||||
:class="{active: currentPage === pages-1}"
|
v-show="currentPage >= (pages - 2)"
|
||||||
@click="goIndex(pages-1)"
|
:class="{active: currentPage === pages-1}"
|
||||||
>
|
@click="goIndex(pages-1)"
|
||||||
{{ pages-1 }}
|
>{{ pages-1 }}</span>
|
||||||
</span>
|
|
||||||
|
|
||||||
<!-- 五号位 -->
|
<!-- 五号位 -->
|
||||||
<span class="card-box"
|
<span
|
||||||
:class="{active: currentPage === pages}"
|
class="card-box"
|
||||||
@click="goIndex(pages)"
|
:class="{active: currentPage === pages}"
|
||||||
>
|
@click="goIndex(pages)"
|
||||||
{{pages}}
|
>{{pages}}</span>
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="card-box next iconfont icon-jiantou-you"
|
<span
|
||||||
:class="{disabled: currentPage === pages}"
|
class="card-box next iconfont icon-jiantou-you"
|
||||||
@click="goNext()"
|
:class="{disabled: currentPage === pages}"
|
||||||
|
@click="goNext()"
|
||||||
>
|
>
|
||||||
<p>下一页</p>
|
<p>下一页</p>
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -98,12 +104,12 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
pages() { // 总页数
|
pages () { // 总页数
|
||||||
return Math.ceil(this.total / this.perPage)
|
return Math.ceil(this.total / this.perPage)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
threeNum() { // 三号位页码计算
|
threeNum () { // 三号位页码计算
|
||||||
let num = 3
|
let num = 3
|
||||||
const currentPage = this.currentPage
|
const currentPage = this.currentPage
|
||||||
const pages = this.pages
|
const pages = this.pages
|
||||||
|
|
@ -116,19 +122,19 @@ export default {
|
||||||
}
|
}
|
||||||
return num
|
return num
|
||||||
},
|
},
|
||||||
goPrex() {
|
goPrex () {
|
||||||
let currentPage = this.currentPage
|
let currentPage = this.currentPage
|
||||||
if (currentPage > 1) {
|
if (currentPage > 1) {
|
||||||
this.handleEmit(--currentPage)
|
this.handleEmit(--currentPage)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
goNext() {
|
goNext () {
|
||||||
let currentPage = this.currentPage
|
let currentPage = this.currentPage
|
||||||
if (currentPage < this.pages) {
|
if (currentPage < this.pages) {
|
||||||
this.handleEmit(++currentPage)
|
this.handleEmit(++currentPage)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
goIndex(i) {
|
goIndex (i) {
|
||||||
if (i !== this.currentPage) {
|
if (i !== this.currentPage) {
|
||||||
this.handleEmit(i)
|
this.handleEmit(i)
|
||||||
}
|
}
|
||||||
|
|
@ -145,18 +151,18 @@ export default {
|
||||||
position relative
|
position relative
|
||||||
height 60px
|
height 60px
|
||||||
text-align center
|
text-align center
|
||||||
span
|
span
|
||||||
line-height 1rem
|
line-height 1rem
|
||||||
opacity .9
|
opacity 0.9
|
||||||
cursor pointer
|
cursor pointer
|
||||||
&:hover
|
&:hover
|
||||||
color $accentColor
|
color $accentColor
|
||||||
&.ellipsis
|
&.ellipsis
|
||||||
opacity .5
|
opacity 0.5
|
||||||
&::before
|
&::before
|
||||||
content '...'
|
content '...'
|
||||||
font-size 1.2rem
|
font-size 1.2rem
|
||||||
@media (any-hover: hover)
|
@media (any-hover hover)
|
||||||
&.ell-two
|
&.ell-two
|
||||||
&:hover
|
&:hover
|
||||||
&::before
|
&::before
|
||||||
|
|
@ -165,14 +171,13 @@ export default {
|
||||||
&:hover
|
&:hover
|
||||||
&::before
|
&::before
|
||||||
content '»'
|
content '»'
|
||||||
|
|
||||||
> span
|
> span
|
||||||
position absolute
|
position absolute
|
||||||
top 0
|
top 0
|
||||||
padding 1rem 1.2rem
|
padding 1rem 1.2rem
|
||||||
font-size .95rem
|
font-size 0.95rem
|
||||||
&.disabled
|
&.disabled
|
||||||
color rgba(125,125,125,.5)
|
color rgba(125, 125, 125, 0.5)
|
||||||
&.prev
|
&.prev
|
||||||
left 0
|
left 0
|
||||||
border-top-right-radius 32px
|
border-top-right-radius 32px
|
||||||
|
|
@ -182,50 +187,47 @@ export default {
|
||||||
border-top-left-radius 32px
|
border-top-left-radius 32px
|
||||||
border-bottom-left-radius 32px
|
border-bottom-left-radius 32px
|
||||||
&::before
|
&::before
|
||||||
float right
|
float right
|
||||||
margin-left .3rem
|
margin-left 0.3rem
|
||||||
p
|
p
|
||||||
display inline
|
display inline
|
||||||
line-height .95rem
|
line-height 0.95rem
|
||||||
.pagination-list
|
.pagination-list
|
||||||
span
|
span
|
||||||
display inline-block
|
display inline-block
|
||||||
width 2.5rem
|
width 2.5rem
|
||||||
height 2.5rem
|
height 2.5rem
|
||||||
line-height 2.5rem
|
line-height 2.5rem
|
||||||
margin .3rem
|
margin 0.3rem
|
||||||
&.active
|
&.active
|
||||||
background $accentColor
|
background $accentColor
|
||||||
color var(--mainBg)
|
color var(--mainBg)
|
||||||
|
@media (max-width 800px)
|
||||||
@media (max-width: 800px)
|
|
||||||
.pagination
|
.pagination
|
||||||
> span
|
> span
|
||||||
padding 1rem 1.5rem
|
padding 1rem 1.5rem
|
||||||
p
|
p
|
||||||
display none
|
display none
|
||||||
|
|
||||||
// 719px
|
// 719px
|
||||||
@media (max-width: $MQMobile)
|
@media (max-width $MQMobile)
|
||||||
.pagination
|
.pagination
|
||||||
> span // 左右按钮
|
> span // 左右按钮
|
||||||
padding .9rem 1.5rem
|
padding 0.9rem 1.5rem
|
||||||
.pagination-list
|
.pagination-list
|
||||||
span
|
span
|
||||||
width 2.3rem
|
width 2.3rem
|
||||||
height 2.3rem
|
height 2.3rem
|
||||||
line-height 2.3rem
|
line-height 2.3rem
|
||||||
margin .25rem
|
margin 0.25rem
|
||||||
|
@media (max-width 390px)
|
||||||
@media (max-width: 390px)
|
|
||||||
.pagination
|
.pagination
|
||||||
> span // 左右按钮
|
> span // 左右按钮
|
||||||
padding .8rem 1.3rem
|
padding 0.8rem 1.3rem
|
||||||
.pagination-list
|
.pagination-list
|
||||||
span
|
span
|
||||||
width 2rem
|
width 2rem
|
||||||
height 2rem
|
height 2rem
|
||||||
line-height 2rem
|
line-height 2rem
|
||||||
margin .1rem
|
margin 0.1rem
|
||||||
margin-top .3rem
|
margin-top 0.3rem
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,46 +1,77 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="post-list" ref="postList">
|
<div
|
||||||
|
class="post-list"
|
||||||
<transition-group tag="div" name="post">
|
ref="postList"
|
||||||
<div class="post card-box" :class="item.frontmatter.sticky && 'iconfont icon-zhiding'" v-for="item in sortPosts" :key="item.key">
|
>
|
||||||
|
<transition-group
|
||||||
|
tag="div"
|
||||||
|
name="post"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="post card-box"
|
||||||
|
:class="item.frontmatter.sticky && 'iconfont icon-zhiding'"
|
||||||
|
v-for="item in sortPosts"
|
||||||
|
:key="item.key"
|
||||||
|
>
|
||||||
<div class="title-wrapper">
|
<div class="title-wrapper">
|
||||||
<h2>
|
<h2>
|
||||||
<router-link :to="item.path">{{item.title}}</router-link>
|
<router-link :to="item.path">{{item.title}}</router-link>
|
||||||
</h2>
|
</h2>
|
||||||
<div class="article-info">
|
<div class="article-info">
|
||||||
<a title="作者" class="iconfont icon-touxiang" target="_blank"
|
<a
|
||||||
v-if="item.author && item.author.href"
|
title="作者"
|
||||||
:href="item.author.href"
|
class="iconfont icon-touxiang"
|
||||||
>
|
target="_blank"
|
||||||
{{ item.author.name ? item.author.name : item.author }}
|
v-if="item.author && item.author.href"
|
||||||
</a>
|
:href="item.author.href"
|
||||||
<span title="作者" class="iconfont icon-touxiang"
|
>{{ item.author.name ? item.author.name : item.author }}</a>
|
||||||
|
<span
|
||||||
|
title="作者"
|
||||||
|
class="iconfont icon-touxiang"
|
||||||
v-else-if="item.author"
|
v-else-if="item.author"
|
||||||
>
|
>{{ item.author.name ? item.author.name : item.author }}</span>
|
||||||
{{ item.author.name ? item.author.name : item.author }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span title="创建时间" class="iconfont icon-riqi" v-if="item.frontmatter.date">
|
<span
|
||||||
{{ item.frontmatter.date.split(' ')[0]}}
|
title="创建时间"
|
||||||
|
class="iconfont icon-riqi"
|
||||||
|
v-if="item.frontmatter.date"
|
||||||
|
>{{ item.frontmatter.date.split(' ')[0]}}</span>
|
||||||
|
<span
|
||||||
|
title="分类"
|
||||||
|
class="iconfont icon-wenjian"
|
||||||
|
v-if="$themeConfig.category !== false && item.frontmatter.categories"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="`/categories/?category=${encodeURIComponent(c)}`"
|
||||||
|
v-for="(c, index) in item.frontmatter.categories"
|
||||||
|
:key="index"
|
||||||
|
>{{c}}</router-link>
|
||||||
</span>
|
</span>
|
||||||
<span title="分类" class="iconfont icon-wenjian" v-if="$themeConfig.category !== false && item.frontmatter.categories">
|
<span
|
||||||
<router-link :to="`/categories/?category=${encodeUrl(c)}`" v-for="(c, index) in item.frontmatter.categories" :key="index">
|
title="标签"
|
||||||
{{c}}
|
class="iconfont icon-biaoqian tags"
|
||||||
</router-link>
|
v-if="$themeConfig.tag !== false && item.frontmatter.tags && item.frontmatter.tags[0]"
|
||||||
</span>
|
>
|
||||||
<span title="标签" class="iconfont icon-biaoqian tags" v-if="$themeConfig.tag !== false && item.frontmatter.tags && item.frontmatter.tags[0]">
|
<router-link
|
||||||
<router-link :to="`/tags/?tag=${encodeUrl(t)}`" v-for="(t, index) in item.frontmatter.tags" :key="index">
|
:to="`/tags/?tag=${encodeURIComponent(t)}`"
|
||||||
{{t}}
|
v-for="(t, index) in item.frontmatter.tags"
|
||||||
</router-link>
|
:key="index"
|
||||||
|
>{{t}}</router-link>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="excerpt-wrapper" v-if="item.excerpt">
|
<div
|
||||||
<div class="excerpt" v-html="item.excerpt">
|
class="excerpt-wrapper"
|
||||||
</div>
|
v-if="item.excerpt"
|
||||||
<router-link :to="item.path" class="readmore iconfont icon-jiantou-you">
|
>
|
||||||
阅读全文
|
<div
|
||||||
</router-link>
|
class="excerpt"
|
||||||
|
v-html="item.excerpt"
|
||||||
|
></div>
|
||||||
|
<router-link
|
||||||
|
:to="item.path"
|
||||||
|
class="readmore iconfont icon-jiantou-you"
|
||||||
|
>阅读全文</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</transition-group>
|
</transition-group>
|
||||||
|
|
@ -48,10 +79,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import encodeMixin from '../mixins/encodeUrl'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [encodeMixin],
|
|
||||||
props: {
|
props: {
|
||||||
category: {
|
category: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|
@ -70,20 +98,20 @@ export default {
|
||||||
default: 10
|
default: 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data () {
|
||||||
return {
|
return {
|
||||||
sortPosts: [],
|
sortPosts: [],
|
||||||
postListOffsetTop: 0
|
postListOffsetTop: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created () {
|
||||||
this.setPosts()
|
this.setPosts()
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted () {
|
||||||
// this.postListOffsetTop = this.getElementToPageTop(this.$refs.postList) - 240
|
// this.postListOffsetTop = this.getElementToPageTop(this.$refs.postList) - 240
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
currentPage() {
|
currentPage () {
|
||||||
if (this.$route.query.p != this.currentPage) { // 此判断防止添加相同的路由信息(如浏览器回退时触发的)
|
if (this.$route.query.p != this.currentPage) { // 此判断防止添加相同的路由信息(如浏览器回退时触发的)
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
query: {
|
query: {
|
||||||
|
|
@ -97,28 +125,28 @@ export default {
|
||||||
// },0)
|
// },0)
|
||||||
this.setPosts()
|
this.setPosts()
|
||||||
},
|
},
|
||||||
category() {
|
category () {
|
||||||
this.setPosts()
|
this.setPosts()
|
||||||
},
|
},
|
||||||
tag() {
|
tag () {
|
||||||
this.setPosts()
|
this.setPosts()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setPosts() {
|
setPosts () {
|
||||||
const currentPage = this.currentPage
|
const currentPage = this.currentPage
|
||||||
const perPage = this.perPage
|
const perPage = this.perPage
|
||||||
|
|
||||||
let posts = []
|
let posts = []
|
||||||
if (this.category) {
|
if (this.category) {
|
||||||
posts = this.$groupPosts.categories[this.category]
|
posts = this.$groupPosts.categories[this.category]
|
||||||
} else if(this.tag){
|
} else if (this.tag) {
|
||||||
posts = this.$groupPosts.tags[this.tag]
|
posts = this.$groupPosts.tags[this.tag]
|
||||||
}else {
|
} else {
|
||||||
posts = this.$sortPosts
|
posts = this.$sortPosts
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sortPosts = posts.slice((currentPage-1)*perPage, currentPage*perPage)
|
this.sortPosts = posts.slice((currentPage - 1) * perPage, currentPage * perPage)
|
||||||
},
|
},
|
||||||
// getElementToPageTop(el) {
|
// getElementToPageTop(el) {
|
||||||
// if(el && el.parentElement) {
|
// if(el && el.parentElement) {
|
||||||
|
|
@ -137,39 +165,39 @@ export default {
|
||||||
position relative
|
position relative
|
||||||
padding 1rem 1.5rem
|
padding 1rem 1.5rem
|
||||||
margin-bottom 0.9rem
|
margin-bottom 0.9rem
|
||||||
transition: all 0.3s
|
transition all 0.3s
|
||||||
&.post-leave-active
|
&.post-leave-active
|
||||||
display none
|
display none
|
||||||
&.post-enter
|
&.post-enter
|
||||||
opacity: 0
|
opacity 0
|
||||||
transform: translateX(-20px)
|
transform translateX(-20px)
|
||||||
&::before
|
&::before
|
||||||
position absolute
|
position absolute
|
||||||
top -1px
|
top -1px
|
||||||
right 0
|
right 0
|
||||||
font-size 2.5rem
|
font-size 2.5rem
|
||||||
color $accentColor
|
color $accentColor
|
||||||
opacity .85
|
opacity 0.85
|
||||||
.title-wrapper
|
.title-wrapper
|
||||||
a
|
a
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
&:hover
|
&:hover
|
||||||
color $accentColor
|
color $accentColor
|
||||||
h2
|
h2
|
||||||
margin .5rem 0
|
margin 0.5rem 0
|
||||||
font-size 1.4rem
|
font-size 1.4rem
|
||||||
border none
|
border none
|
||||||
a
|
a
|
||||||
@media (max-width: $MQMobile)
|
@media (max-width $MQMobile)
|
||||||
font-weight 400
|
font-weight 400
|
||||||
.article-info
|
.article-info
|
||||||
> a, > span
|
> a, > span
|
||||||
opacity .7
|
opacity 0.7
|
||||||
font-size .8rem
|
font-size 0.8rem
|
||||||
margin-right 1rem
|
margin-right 1rem
|
||||||
cursor pointer
|
cursor pointer
|
||||||
&::before
|
&::before
|
||||||
margin-right .3rem
|
margin-right 0.3rem
|
||||||
a
|
a
|
||||||
margin 0
|
margin 0
|
||||||
&:not(:first-child)
|
&:not(:first-child)
|
||||||
|
|
@ -177,26 +205,25 @@ export default {
|
||||||
content '/'
|
content '/'
|
||||||
.tags a:not(:first-child)::before
|
.tags a:not(:first-child)::before
|
||||||
content '、'
|
content '、'
|
||||||
|
|
||||||
.excerpt-wrapper
|
.excerpt-wrapper
|
||||||
border-top 1px solid var(--borderColor)
|
border-top 1px solid var(--borderColor)
|
||||||
margin .5rem 0
|
margin 0.5rem 0
|
||||||
overflow hidden
|
overflow hidden
|
||||||
.excerpt
|
.excerpt
|
||||||
margin-bottom .3rem
|
margin-bottom 0.3rem
|
||||||
font-size 0.92rem
|
font-size 0.92rem
|
||||||
h1,h2,h3
|
h1, h2, h3
|
||||||
display none
|
display none
|
||||||
img
|
img
|
||||||
max-height 280px
|
max-height 280px
|
||||||
max-width 100%!important
|
max-width 100% !important
|
||||||
margin 0 auto
|
margin 0 auto
|
||||||
.readmore
|
.readmore
|
||||||
float right
|
float right
|
||||||
margin-right 1rem
|
margin-right 1rem
|
||||||
line-height 1rem
|
line-height 1rem
|
||||||
&::before
|
&::before
|
||||||
float right
|
float right
|
||||||
font-size .8rem
|
font-size 0.8rem
|
||||||
margin .1rem 0 0 .2rem
|
margin 0.1rem 0 0 0.2rem
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
<div class="right-menu-margin">
|
<div class="right-menu-margin">
|
||||||
<div class="right-menu-content">
|
<div class="right-menu-content">
|
||||||
<div
|
<div
|
||||||
:class="['right-menu-item', 'level'+item.level, { active: item.slug === hashText }]"
|
:class="['right-menu-item', 'level'+item.level, { active: item.slug === hashText }]"
|
||||||
v-for="(item, i) in headers"
|
v-for="(item, i) in headers"
|
||||||
:key="i"
|
:key="i"
|
||||||
>
|
>
|
||||||
<a :href="'#'+item.slug">{{item.title}}</a>
|
<a :href="'#'+item.slug">{{item.title}}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -16,27 +16,27 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data () {
|
||||||
return {
|
return {
|
||||||
headers: [],
|
headers: [],
|
||||||
hashText: ''
|
hashText: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted () {
|
||||||
this.getHeadersData()
|
this.getHeadersData()
|
||||||
this.getHashText()
|
this.getHashText()
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route() {
|
$route () {
|
||||||
this.headers = this.$page.headers
|
this.headers = this.$page.headers
|
||||||
this.getHashText()
|
this.getHashText()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getHeadersData() {
|
getHeadersData () {
|
||||||
this.headers = this.$page.headers
|
this.headers = this.$page.headers
|
||||||
},
|
},
|
||||||
getHashText() {
|
getHashText () {
|
||||||
this.hashText = decodeURIComponent(window.location.hash.slice(1))
|
this.hashText = decodeURIComponent(window.location.hash.slice(1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -44,14 +44,13 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang='stylus'>
|
<style lang='stylus'>
|
||||||
|
|
||||||
.right-menu-wrapper
|
.right-menu-wrapper
|
||||||
width $rightMenuWidth
|
width $rightMenuWidth
|
||||||
float right
|
float right
|
||||||
margin-right -($rightMenuWidth + 60px)
|
margin-right -($rightMenuWidth + 60px)
|
||||||
position sticky
|
position sticky
|
||||||
top 0
|
top 0
|
||||||
font-size .9rem
|
font-size 0.9rem
|
||||||
.right-menu-margin
|
.right-menu-margin
|
||||||
margin-top ($navbarHeight + 1rem)
|
margin-top ($navbarHeight + 1rem)
|
||||||
.right-menu-content
|
.right-menu-content
|
||||||
|
|
@ -61,12 +60,12 @@ export default {
|
||||||
&::-webkit-scrollbar-track-piece
|
&::-webkit-scrollbar-track-piece
|
||||||
background none
|
background none
|
||||||
&::-webkit-scrollbar-thumb:vertical
|
&::-webkit-scrollbar-thumb:vertical
|
||||||
background-color hsla(0,0%,49%,.3)
|
background-color hsla(0, 0%, 49%, 0.3)
|
||||||
&:hover
|
&:hover
|
||||||
overflow-y auto
|
overflow-y auto
|
||||||
.right-menu-item
|
.right-menu-item
|
||||||
padding 4px 15px
|
padding 4px 15px
|
||||||
border-left .15rem solid var(--borderColor)
|
border-left 0.15rem solid var(--borderColor)
|
||||||
&.level3
|
&.level3
|
||||||
padding-left 28px
|
padding-left 28px
|
||||||
&.active
|
&.active
|
||||||
|
|
@ -81,17 +80,16 @@ export default {
|
||||||
width ($rightMenuWidth - 30px)
|
width ($rightMenuWidth - 30px)
|
||||||
&:hover
|
&:hover
|
||||||
color $accentColor
|
color $accentColor
|
||||||
|
.have-body-img
|
||||||
.have-body-img
|
|
||||||
.right-menu-wrapper
|
.right-menu-wrapper
|
||||||
.right-menu-margin
|
.right-menu-margin
|
||||||
padding .3rem 0
|
padding 0.3rem 0
|
||||||
background var(--sidebarBg)
|
background var(--sidebarBg)
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
.right-menu-item
|
.right-menu-item
|
||||||
border-color transparent
|
border-color transparent
|
||||||
&.active
|
&.active
|
||||||
border-left .2rem solid $accentColor
|
border-left 0.2rem solid $accentColor
|
||||||
&:hover
|
&:hover
|
||||||
border-left .2rem solid $accentColor
|
border-left 0.2rem solid $accentColor
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<aside class="sidebar">
|
<aside class="sidebar">
|
||||||
<div class="blogger" v-if="blogger">
|
<div
|
||||||
<img :src="blogger.avatar">
|
class="blogger"
|
||||||
|
v-if="blogger"
|
||||||
|
>
|
||||||
|
<img :src="blogger.avatar" />
|
||||||
<div class="blogger-info">
|
<div class="blogger-info">
|
||||||
<h3>{{blogger.name}}</h3>
|
<h3>{{blogger.name}}</h3>
|
||||||
|
|
||||||
<div class="icons" v-if="blogger.social">
|
<div
|
||||||
|
class="icons"
|
||||||
|
v-if="blogger.social"
|
||||||
|
>
|
||||||
<a
|
<a
|
||||||
:href="item.link"
|
:href="item.link"
|
||||||
:title="item.title"
|
:title="item.title"
|
||||||
|
|
@ -13,18 +19,18 @@
|
||||||
v-for="(item, index) in blogger.social.icons"
|
v-for="(item, index) in blogger.social.icons"
|
||||||
:key="index"
|
:key="index"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
></a>
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
<span v-else>
|
<span v-else>{{blogger.slogan}}</span>
|
||||||
{{blogger.slogan}}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<NavLinks/>
|
<NavLinks />
|
||||||
<slot name="top"/>
|
<slot name="top" />
|
||||||
<SidebarLinks :depth="0" :items="items"/>
|
<SidebarLinks
|
||||||
<slot name="bottom"/>
|
:depth="0"
|
||||||
|
:items="items"
|
||||||
|
/>
|
||||||
|
<slot name="bottom" />
|
||||||
</aside>
|
</aside>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -38,9 +44,9 @@ export default {
|
||||||
components: { SidebarLinks, NavLinks },
|
components: { SidebarLinks, NavLinks },
|
||||||
|
|
||||||
props: ['items'],
|
props: ['items'],
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
blogger() {
|
blogger () {
|
||||||
return this.$themeConfig.blogger
|
return this.$themeConfig.blogger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -73,7 +79,7 @@ export default {
|
||||||
line-height 1.7
|
line-height 1.7
|
||||||
font-weight bold
|
font-weight bold
|
||||||
& > li:not(:first-child)
|
& > li:not(:first-child)
|
||||||
margin-top .75rem
|
margin-top 0.75rem
|
||||||
.blogger
|
.blogger
|
||||||
display none
|
display none
|
||||||
border-bottom 1px solid var(--borderColor)
|
border-bottom 1px solid var(--borderColor)
|
||||||
|
|
@ -81,17 +87,17 @@ export default {
|
||||||
width 60px
|
width 60px
|
||||||
height 60px
|
height 60px
|
||||||
border-radius 5px
|
border-radius 5px
|
||||||
margin .75rem 1rem
|
margin 0.75rem 1rem
|
||||||
.blogger-info
|
.blogger-info
|
||||||
flex 1
|
flex 1
|
||||||
h3
|
h3
|
||||||
margin .95rem 0 .7rem
|
margin 0.95rem 0 0.7rem
|
||||||
font-size 1.1rem
|
font-size 1.1rem
|
||||||
.icons .iconfont
|
.icons .iconfont
|
||||||
font-size 1.2rem
|
font-size 1.2rem
|
||||||
padding-right .6rem
|
padding-right 0.6rem
|
||||||
color #777
|
color #777
|
||||||
@media (max-width: $MQMobile)
|
@media (max-width $MQMobile)
|
||||||
.sidebar
|
.sidebar
|
||||||
.blogger
|
.blogger
|
||||||
display flex
|
display flex
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,21 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="sidebar-button" @click="$emit('toggle-sidebar')" title="目录">
|
<div
|
||||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512">
|
class="sidebar-button"
|
||||||
<path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z" class=""></path>
|
@click="$emit('toggle-sidebar')"
|
||||||
|
title="目录"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="icon"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
aria-hidden="true"
|
||||||
|
role="img"
|
||||||
|
viewBox="0 0 448 512"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"
|
||||||
|
class
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -16,14 +30,13 @@
|
||||||
padding 0.6rem
|
padding 0.6rem
|
||||||
top 0.6rem
|
top 0.6rem
|
||||||
left 1rem
|
left 1rem
|
||||||
@media (max-width: $MQMobile)
|
@media (max-width $MQMobile)
|
||||||
display block
|
display block
|
||||||
.icon
|
.icon
|
||||||
display block
|
display block
|
||||||
width 1.25rem
|
width 1.25rem
|
||||||
height 1.25rem
|
height 1.25rem
|
||||||
|
@media (min-width ($MQMobile + 1px))
|
||||||
@media (min-width: ($MQMobile + 1px))
|
|
||||||
$mobileSidebarWidth = $sidebarWidth * 0.82
|
$mobileSidebarWidth = $sidebarWidth * 0.82
|
||||||
.sidebar-button
|
.sidebar-button
|
||||||
width 40px
|
width 40px
|
||||||
|
|
@ -38,7 +51,7 @@
|
||||||
color #888
|
color #888
|
||||||
border-radius 50%
|
border-radius 50%
|
||||||
padding 0
|
padding 0
|
||||||
transition left .2s ease
|
transition left 0.2s ease
|
||||||
&:hover
|
&:hover
|
||||||
background $accentColor
|
background $accentColor
|
||||||
color #fff
|
color #fff
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@
|
||||||
<span
|
<span
|
||||||
class="arrow"
|
class="arrow"
|
||||||
v-if="collapsable"
|
v-if="collapsable"
|
||||||
:class="open ? 'down' : 'right'">
|
:class="open ? 'down' : 'right'"
|
||||||
</span>
|
></span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
<p
|
<p
|
||||||
|
|
@ -37,8 +37,8 @@
|
||||||
<span
|
<span
|
||||||
class="arrow"
|
class="arrow"
|
||||||
v-if="collapsable"
|
v-if="collapsable"
|
||||||
:class="open ? 'down' : 'right'">
|
:class="open ? 'down' : 'right'"
|
||||||
</span>
|
></span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<DropdownTransition>
|
<DropdownTransition>
|
||||||
|
|
@ -90,15 +90,14 @@ export default {
|
||||||
& > .sidebar-group-items
|
& > .sidebar-group-items
|
||||||
padding-left 1rem
|
padding-left 1rem
|
||||||
& > li > .sidebar-link
|
& > li > .sidebar-link
|
||||||
font-size: 0.95em;
|
font-size 0.95em
|
||||||
border-left none
|
border-left none
|
||||||
&.depth-2
|
&.depth-2
|
||||||
& > .sidebar-heading
|
& > .sidebar-heading
|
||||||
border-left none
|
border-left none
|
||||||
|
|
||||||
.sidebar-heading
|
.sidebar-heading
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
transition color .15s ease
|
transition color 0.15s ease
|
||||||
cursor pointer
|
cursor pointer
|
||||||
font-size 1.1em
|
font-size 1.1em
|
||||||
font-weight bold
|
font-weight bold
|
||||||
|
|
@ -121,9 +120,8 @@ export default {
|
||||||
border-left-color $accentColor
|
border-left-color $accentColor
|
||||||
&:hover
|
&:hover
|
||||||
color $accentColor
|
color $accentColor
|
||||||
|
|
||||||
.sidebar-group-items
|
.sidebar-group-items
|
||||||
transition height .1s ease-out
|
transition height 0.1s ease-out
|
||||||
font-size 0.95em
|
font-size 0.95em
|
||||||
overflow hidden
|
overflow hidden
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@ function renderExternal (h, to, text) {
|
||||||
.sidebar .sidebar-sub-headers
|
.sidebar .sidebar-sub-headers
|
||||||
padding-left 1rem
|
padding-left 1rem
|
||||||
font-size 0.95em
|
font-size 0.95em
|
||||||
|
|
||||||
a.sidebar-link
|
a.sidebar-link
|
||||||
font-size 1em
|
font-size 1em
|
||||||
font-weight 400
|
font-weight 400
|
||||||
|
|
@ -106,8 +105,8 @@ a.sidebar-link
|
||||||
border-left 0.25rem solid transparent
|
border-left 0.25rem solid transparent
|
||||||
padding 0.35rem 1rem 0.35rem 1.25rem
|
padding 0.35rem 1rem 0.35rem 1.25rem
|
||||||
line-height 1.4
|
line-height 1.4
|
||||||
width: 100%
|
width 100%
|
||||||
box-sizing: border-box
|
box-sizing border-box
|
||||||
&:hover
|
&:hover
|
||||||
color $accentColor
|
color $accentColor
|
||||||
&.active
|
&.active
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,10 @@
|
||||||
class="sidebar-links"
|
class="sidebar-links"
|
||||||
v-if="items.length"
|
v-if="items.length"
|
||||||
>
|
>
|
||||||
<li v-for="(item, i) in items" :key="i">
|
<li
|
||||||
|
v-for="(item, i) in items"
|
||||||
|
:key="i"
|
||||||
|
>
|
||||||
<SidebarGroup
|
<SidebarGroup
|
||||||
v-if="item.type === 'group'"
|
v-if="item.type === 'group'"
|
||||||
:item="item"
|
:item="item"
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,24 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="tags-wrapper card-box">
|
<div class="tags-wrapper card-box">
|
||||||
<router-link to="/tags/" class="title iconfont icon-biaoqian1" title="全部标签">
|
<router-link
|
||||||
{{ length === 'all' ? '全部标签' : '热门标签' }}
|
to="/tags/"
|
||||||
</router-link>
|
class="title iconfont icon-biaoqian1"
|
||||||
|
title="全部标签"
|
||||||
|
>{{ length === 'all' ? '全部标签' : '热门标签' }}</router-link>
|
||||||
<div class="tags">
|
<div class="tags">
|
||||||
<template v-for="(item, index) in tags" >
|
<template v-for="(item, index) in tags">
|
||||||
<router-link
|
<router-link
|
||||||
:to="`/tags/?tag=${item.key}`"
|
:to="`/tags/?tag=${encodeURIComponent(item.key)}`"
|
||||||
:key="index"
|
:key="index"
|
||||||
:style="tagStyleList[index]"
|
:style="tagStyleList[index]"
|
||||||
:class="{active: item.key === tag}"
|
:class="{active: item.key === tag}"
|
||||||
>
|
>{{item.key}}</router-link>
|
||||||
{{item.key}}
|
<span :key="index+tags.length" />
|
||||||
</router-link>
|
|
||||||
<span :key="index+tags.length"/>
|
|
||||||
</template>
|
</template>
|
||||||
<router-link to="/tags/" v-if="length !== 'all' && tagsData.length > length">
|
<router-link
|
||||||
更多...
|
to="/tags/"
|
||||||
</router-link>
|
v-if="length !== 'all' && tagsData.length > length"
|
||||||
|
>更多...</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -38,19 +39,19 @@ export default {
|
||||||
default: 'all'
|
default: 'all'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data () {
|
||||||
return {
|
return {
|
||||||
tagBgColor: ['#11a8cd', '#F8B26A', '#67CC86', '#E15B64', '#F47E60', '#849B87'],
|
tagBgColor: ['#11a8cd', '#F8B26A', '#67CC86', '#E15B64', '#F47E60', '#849B87'],
|
||||||
tagStyleList: []
|
tagStyleList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created () {
|
||||||
for (let i = 0, tagH = this.tags.length; i < tagH; i++) {
|
for (let i = 0, tagH = this.tags.length; i < tagH; i++) {
|
||||||
this.tagStyleList.push(this.getTagStyle())
|
this.tagStyleList.push(this.getTagStyle())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
tags() {
|
tags () {
|
||||||
if (this.length === 'all') {
|
if (this.length === 'all') {
|
||||||
return this.tagsData
|
return this.tagsData
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -59,7 +60,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getTagStyle() {
|
getTagStyle () {
|
||||||
const tagBgColor = this.tagBgColor
|
const tagBgColor = this.tagBgColor
|
||||||
const randomColor = tagBgColor[Math.floor(Math.random() * tagBgColor.length)]
|
const randomColor = tagBgColor[Math.floor(Math.random() * tagBgColor.length)]
|
||||||
return `background: ${randomColor};--randomColor:${randomColor};`
|
return `background: ${randomColor};--randomColor:${randomColor};`
|
||||||
|
|
@ -69,36 +70,36 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang='stylus'>
|
<style lang='stylus'>
|
||||||
.tags-wrapper
|
.tags-wrapper
|
||||||
.title
|
.title
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
opacity 0.9
|
opacity 0.9
|
||||||
font-size 1.2rem
|
font-size 1.2rem
|
||||||
.tags
|
.tags
|
||||||
text-align justify
|
text-align justify
|
||||||
padding .8rem .5rem .5rem .5rem
|
padding 0.8rem 0.5rem 0.5rem 0.5rem
|
||||||
margin 0 -0.5rem -0.5rem -0.5rem
|
margin 0 -0.5rem -0.5rem -0.5rem
|
||||||
a
|
a
|
||||||
opacity .8
|
opacity 0.8
|
||||||
display inline-block
|
display inline-block
|
||||||
padding .2rem .4rem
|
padding 0.2rem 0.4rem
|
||||||
transition all .4s
|
transition all 0.4s
|
||||||
background-color var(--textColor)
|
background-color var(--textColor)
|
||||||
color var(--mainBg)
|
color var(--mainBg)
|
||||||
border-radius 3px
|
border-radius 3px
|
||||||
margin 0 .3rem .5rem 0
|
margin 0 0.3rem 0.5rem 0
|
||||||
min-width 2rem
|
min-width 2rem
|
||||||
height 1rem
|
height 1rem
|
||||||
line-height 1rem
|
line-height 1rem
|
||||||
font-size .8rem
|
font-size 0.8rem
|
||||||
text-align center
|
text-align center
|
||||||
@media (max-width: $MQMobile)
|
@media (max-width $MQMobile)
|
||||||
font-weight 400
|
font-weight 400
|
||||||
&:hover
|
&:hover
|
||||||
opacity 1
|
opacity 1
|
||||||
transform scale(1.1)
|
transform scale(1.1)
|
||||||
&.active
|
&.active
|
||||||
box-shadow: 0 5px 10px -5px var(--randomColor, rgba(0,0,0,0.15));
|
box-shadow 0 5px 10px -5px var(--randomColor, rgba(0, 0, 0, 0.15))
|
||||||
transform scale(1.22)
|
transform scale(1.22)
|
||||||
opacity 1
|
opacity 1
|
||||||
&:hover
|
&:hover
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ import Pagination from '@theme/components/Pagination'
|
||||||
import TagsBar from '@theme/components/TagsBar'
|
import TagsBar from '@theme/components/TagsBar'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data(){
|
data () {
|
||||||
return {
|
return {
|
||||||
tag: '',
|
tag: '',
|
||||||
total: 0, // 总长
|
total: 0, // 总长
|
||||||
|
|
@ -47,9 +47,9 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: { MainLayout, PostList, Pagination, TagsBar },
|
components: { MainLayout, PostList, Pagination, TagsBar },
|
||||||
mounted() {
|
mounted () {
|
||||||
const queryTag = this.$route.query.tag
|
const queryTag = this.$route.query.tag
|
||||||
|
|
||||||
if (queryTag) {
|
if (queryTag) {
|
||||||
this.tag = queryTag
|
this.tag = queryTag
|
||||||
this.total = this.$groupPosts.tags[queryTag].length
|
this.total = this.$groupPosts.tags[queryTag].length
|
||||||
|
|
@ -61,13 +61,13 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handlePagination(i) { // 分页
|
handlePagination (i) { // 分页
|
||||||
this.currentPage = i
|
this.currentPage = i
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route.query.tag'() {
|
'$route.query.tag' () {
|
||||||
this.tag = this.$route.query.tag
|
this.tag = decodeURIComponent(this.$route.query.tag)
|
||||||
if (this.tag) {
|
if (this.tag) {
|
||||||
this.total = this.$groupPosts.tags[this.tag].length
|
this.total = this.$groupPosts.tags[this.tag].length
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -82,42 +82,40 @@ export default {
|
||||||
|
|
||||||
<style lang='stylus'>
|
<style lang='stylus'>
|
||||||
.tags-page
|
.tags-page
|
||||||
.tags-wrapper
|
.tags-wrapper
|
||||||
position sticky
|
position sticky
|
||||||
top ($navbarHeight + .9rem)
|
top ($navbarHeight + 0.9rem)
|
||||||
max-height calc(100vh - 10rem)
|
max-height calc(100vh - 10rem)
|
||||||
min-height 4.2rem
|
min-height 4.2rem
|
||||||
@media (max-width: $MQMobile)
|
@media (max-width $MQMobile)
|
||||||
display none
|
display none
|
||||||
.tags
|
.tags
|
||||||
max-height calc(100vh - 14rem)
|
max-height calc(100vh - 14rem)
|
||||||
min-height 2.2rem
|
min-height 2.2rem
|
||||||
overflow-x hidden
|
overflow-x hidden
|
||||||
overflow-y auto
|
overflow-y auto
|
||||||
transition all .2s
|
transition all 0.2s
|
||||||
&::-webkit-scrollbar-track-piece
|
&::-webkit-scrollbar-track-piece
|
||||||
background-color:rgba(0,0,0,.05)
|
background-color rgba(0, 0, 0, 0.05)
|
||||||
&::-webkit-scrollbar-thumb:vertical
|
&::-webkit-scrollbar-thumb:vertical
|
||||||
background-color:rgba(0,0,0,.15)
|
background-color rgba(0, 0, 0, 0.15)
|
||||||
&:hover
|
&:hover
|
||||||
&::-webkit-scrollbar-track-piece
|
&::-webkit-scrollbar-track-piece
|
||||||
background-color:rgba(0,0,0,.1)
|
background-color rgba(0, 0, 0, 0.1)
|
||||||
&::-webkit-scrollbar-thumb:vertical
|
&::-webkit-scrollbar-thumb:vertical
|
||||||
background-color:rgba(0,0,0,.25)
|
background-color rgba(0, 0, 0, 0.25)
|
||||||
|
|
||||||
.tags-page
|
.tags-page
|
||||||
.main-left
|
.main-left
|
||||||
.tags-wrapper
|
.tags-wrapper
|
||||||
position relative
|
position relative
|
||||||
top 0
|
top 0
|
||||||
padding .9rem 1.5rem
|
padding 0.9rem 1.5rem
|
||||||
margin-bottom .9rem
|
margin-bottom 0.9rem
|
||||||
max-height 15rem
|
max-height 15rem
|
||||||
border-radius 0
|
border-radius 0
|
||||||
display none
|
display none
|
||||||
@media (max-width: $MQMobile)
|
@media (max-width $MQMobile)
|
||||||
display block
|
display block
|
||||||
.tags
|
.tags
|
||||||
max-height 11.5rem
|
max-height 11.5rem
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,226 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="timeline-wrapper theme-vdoing-content">
|
|
||||||
<div class="tags">
|
|
||||||
<a href="#全部" :class="{active: currentTag === '全部'}" :style="randomBgcolor()" @click="toggleTag('全部')">全部</a>
|
|
||||||
<a
|
|
||||||
:class="{active: currentTag === key}"
|
|
||||||
v-for="(item, key) of getPages.tagGroup"
|
|
||||||
:style="randomBgcolor()"
|
|
||||||
@click="toggleTag(key)"
|
|
||||||
:key="key"
|
|
||||||
:href="'#'+key"
|
|
||||||
>
|
|
||||||
{{key}}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="timeline">
|
|
||||||
<transition-group tag="ul">
|
|
||||||
<li class="desc" key="0">{{pageData.slogan}}</li>
|
|
||||||
<template v-for="yearItem in tagPages()">
|
|
||||||
<li :key="yearItem.year">
|
|
||||||
<h3 class="year">{{yearItem.year}}</h3>
|
|
||||||
<div class="year-wrapper">
|
|
||||||
<transition-group tag="span">
|
|
||||||
<router-link :to="item.path" v-for="item in yearItem.pageList" :key="item.path.slice(-6)">
|
|
||||||
<span class="date">{{item.formatDay}}</span>
|
|
||||||
<span class="title">{{item.title}}</span>
|
|
||||||
</router-link>
|
|
||||||
</transition-group>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
</transition-group>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getPagesList } from '../util/getArticleDate'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
pageData: {
|
|
||||||
tagBgColor: ['#11a8cd', '#F8B26A', '#67CC86', '#E15B64', '#F47E60', '#849B87'],
|
|
||||||
slogan: '只争朝夕,不负韶华!( •̀ ω •́ )✧'
|
|
||||||
},
|
|
||||||
currentTag: "",
|
|
||||||
posts: [],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
const fmData = this.$frontmatter.pageComponent.data
|
|
||||||
if(fmData && fmData.slogan) {
|
|
||||||
this.pageData.slogan = fmData.slogan
|
|
||||||
}
|
|
||||||
|
|
||||||
this.posts = this.$site.pages
|
|
||||||
document.body.style="overflow-y: scroll;" // 解决切换tag页面高度不满屏出现跳动的问题
|
|
||||||
|
|
||||||
this.handleHashTag()
|
|
||||||
|
|
||||||
window.onhashchange = () => {
|
|
||||||
this.handleHashTag()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
getPages() {
|
|
||||||
return getPagesList(this.posts)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
currentTag(tag) {
|
|
||||||
document.body.setAttribute('id', tag); // 用于解决vue-router在处理描点元素定位时的报错
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
handleHashTag() {
|
|
||||||
const hashTag = decodeURIComponent(window.location.hash.slice(1))
|
|
||||||
this.currentTag = hashTag ? hashTag : '全部'
|
|
||||||
},
|
|
||||||
// 根据标签获取数据
|
|
||||||
tagPages() {
|
|
||||||
if (this.currentTag === "全部") {
|
|
||||||
return this.getPages.allPage
|
|
||||||
} else {
|
|
||||||
return this.getPages.tagGroup[this.currentTag]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 切换标签
|
|
||||||
toggleTag(tag) {
|
|
||||||
this.currentTag = tag
|
|
||||||
},
|
|
||||||
|
|
||||||
// 随机背景色
|
|
||||||
randomBgcolor() {
|
|
||||||
const tagBgColor = this.pageData.tagBgColor
|
|
||||||
return { background: `${tagBgColor[Math.floor(Math.random() * tagBgColor.length)]}`}
|
|
||||||
},
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="stylus" rel="stylesheet/stylus">
|
|
||||||
.timeline-wrapper
|
|
||||||
padding-top 1rem
|
|
||||||
.tags
|
|
||||||
margin-bottom 30px
|
|
||||||
a
|
|
||||||
vertical-align: middle;
|
|
||||||
margin: 4px 4px 10px;
|
|
||||||
padding: 5px 8px;
|
|
||||||
display: inline-block;
|
|
||||||
cursor: pointer;
|
|
||||||
border-radius: .25rem;
|
|
||||||
background: #E15B64;
|
|
||||||
color: #fff;
|
|
||||||
line-height: 13px;
|
|
||||||
font-size: 13px;
|
|
||||||
transition: all .5s;
|
|
||||||
opacity: 0.9;
|
|
||||||
box-shadow: 0px 0px 8px rgba(80,80,80,.3);
|
|
||||||
&.active
|
|
||||||
transform: scale(1.2);
|
|
||||||
opacity: 1;
|
|
||||||
&:hover
|
|
||||||
text-decoration: none!important;
|
|
||||||
&:not(.active):hover
|
|
||||||
transform: scale(1.05);
|
|
||||||
|
|
||||||
|
|
||||||
.v-enter{
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-30px);
|
|
||||||
}
|
|
||||||
.v-leave-active{
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
.v-leave{
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ul
|
|
||||||
list-style: none;
|
|
||||||
.timeline ul
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 4rem auto;
|
|
||||||
position: relative;
|
|
||||||
&:after
|
|
||||||
content: " ";
|
|
||||||
position: absolute;
|
|
||||||
top: 14px;
|
|
||||||
left: 0;
|
|
||||||
// z-index: -1;
|
|
||||||
margin-left: -2px;
|
|
||||||
width: 4px;
|
|
||||||
height: 100%;
|
|
||||||
background: var(--borderColor);
|
|
||||||
>li
|
|
||||||
transition: all .25s ease-in-out;
|
|
||||||
margin-bottom: 55px;
|
|
||||||
.year
|
|
||||||
margin: 0;
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 26px;
|
|
||||||
.desc,.year
|
|
||||||
position: relative;
|
|
||||||
.desc:before,.year:before
|
|
||||||
content: " ";
|
|
||||||
position: absolute;
|
|
||||||
z-index: 2;
|
|
||||||
left: -20px;
|
|
||||||
top: 50%;
|
|
||||||
margin-left: -4px;
|
|
||||||
margin-top: -4px;
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid var(--borderColor);
|
|
||||||
border-radius: 50%;
|
|
||||||
.year-wrapper
|
|
||||||
padding-left: 0!important;
|
|
||||||
a
|
|
||||||
display: flex;
|
|
||||||
padding: 30px 0 10px;
|
|
||||||
list-style: none;
|
|
||||||
border-bottom: 1px dashed var(--borderColor);
|
|
||||||
position: relative;
|
|
||||||
color: var(--textColor)
|
|
||||||
transition: all 0.25s ease-in-out;
|
|
||||||
.title
|
|
||||||
opacity .9
|
|
||||||
.date
|
|
||||||
min-width: 40px;
|
|
||||||
line-height: 30px;
|
|
||||||
font-size: 13px;
|
|
||||||
margin-right: 5px;
|
|
||||||
color: #999;
|
|
||||||
&:before
|
|
||||||
content: " ";
|
|
||||||
position: absolute;
|
|
||||||
left: -19px;
|
|
||||||
top: 41px;
|
|
||||||
width: 6px;
|
|
||||||
height: 6px;
|
|
||||||
margin-left: -4px;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: 1px solid var(--borderColor);
|
|
||||||
z-index: 2;
|
|
||||||
&:hover
|
|
||||||
text-decoration:none
|
|
||||||
color: $accentColor
|
|
||||||
.date
|
|
||||||
color: $accentColor
|
|
||||||
.date:before
|
|
||||||
background: $accentColor
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,25 +1,35 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="['article-list',{'no-article-list': isShowArticle}]">
|
<div :class="['article-list',{'no-article-list': isShowArticle}]">
|
||||||
<div class="article-title">
|
<div class="article-title">
|
||||||
<router-link :to="moreArticle || '/archives/'" class="iconfont icon-bi">最近更新</router-link>
|
<router-link
|
||||||
|
:to="moreArticle || '/archives/'"
|
||||||
|
class="iconfont icon-bi"
|
||||||
|
>最近更新</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="article-wrapper">
|
<div class="article-wrapper">
|
||||||
<dl v-for="(item, index) in topPublishPosts" :key="index">
|
<dl
|
||||||
|
v-for="(item, index) in topPublishPosts"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
<dd>{{getNum(index)}}</dd>
|
<dd>{{getNum(index)}}</dd>
|
||||||
<dt>
|
<dt>
|
||||||
<router-link :to="item.path"><div>{{item.title}}</div></router-link>
|
<router-link :to="item.path">
|
||||||
|
<div>{{item.title}}</div>
|
||||||
|
</router-link>
|
||||||
<span>{{getDate(item)}}</span>
|
<span>{{getDate(item)}}</span>
|
||||||
</dt>
|
</dt>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dd></dd>
|
<dd></dd>
|
||||||
<dt>
|
<dt>
|
||||||
<router-link :to="moreArticle || '/archives/'" class="more">更多文章></router-link>
|
<router-link
|
||||||
|
:to="moreArticle || '/archives/'"
|
||||||
|
class="more"
|
||||||
|
>更多文章></router-link>
|
||||||
</dt>
|
</dt>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -34,19 +44,19 @@ export default {
|
||||||
},
|
},
|
||||||
moreArticle: String
|
moreArticle: String
|
||||||
},
|
},
|
||||||
data() {
|
data () {
|
||||||
return {
|
return {
|
||||||
posts: [],
|
posts: [],
|
||||||
currentPath: ''
|
currentPath: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created () {
|
||||||
this.posts = this.$site.pages
|
this.posts = this.$site.pages
|
||||||
this.currentPath = this.$page.path
|
this.currentPath = this.$page.path
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
topPublishPosts() {
|
topPublishPosts () {
|
||||||
return this.$sortPostsByDate ? this.$sortPostsByDate.filter( post => {
|
return this.$sortPostsByDate ? this.$sortPostsByDate.filter(post => {
|
||||||
const { path } = post
|
const { path } = post
|
||||||
return path !== this.currentPath
|
return path !== this.currentPath
|
||||||
}).slice(0, this.length) : []
|
}).slice(0, this.length) : []
|
||||||
|
|
@ -58,15 +68,15 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getNum(index) {
|
getNum (index) {
|
||||||
return index < 9 ? '0' + (index + 1) : index + 1
|
return index < 9 ? '0' + (index + 1) : index + 1
|
||||||
},
|
},
|
||||||
getDate(item) {
|
getDate (item) {
|
||||||
return item.frontmatter.date ? item.frontmatter.date.split(" ")[0].slice(5,10) : ''
|
return item.frontmatter.date ? item.frontmatter.date.split(" ")[0].slice(5, 10) : ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route() {
|
$route () {
|
||||||
this.currentPath = this.$page.path
|
this.currentPath = this.$page.path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -74,68 +84,68 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang='stylus'>
|
<style lang='stylus'>
|
||||||
// @require '../styles/wrapper.styl'
|
// @require '../styles/wrapper.styl'
|
||||||
.article-list
|
.article-list
|
||||||
// @extend $wrapper
|
// @extend $wrapper
|
||||||
padding 1rem 2rem
|
padding 1rem 2rem
|
||||||
@media (max-width: $MQNarrow)
|
@media (max-width $MQNarrow)
|
||||||
padding 1rem 1.5rem
|
padding 1rem 1.5rem
|
||||||
&.no-article-list
|
&.no-article-list
|
||||||
display none
|
display none
|
||||||
.article-title
|
.article-title
|
||||||
border-bottom 1px solid var(--borderColor)
|
border-bottom 1px solid var(--borderColor)
|
||||||
font-size 1.3rem
|
font-size 1.3rem
|
||||||
padding 1rem
|
padding 1rem
|
||||||
a
|
a
|
||||||
font-size 1.2rem
|
font-size 1.2rem
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
opacity 0.9
|
opacity 0.9
|
||||||
&:before
|
&:before
|
||||||
margin-right .4rem
|
margin-right 0.4rem
|
||||||
font-size 1.1rem
|
font-size 1.1rem
|
||||||
.article-wrapper
|
.article-wrapper
|
||||||
overflow hidden
|
overflow hidden
|
||||||
dl
|
dl
|
||||||
border-bottom 1px dotted var(--borderColor)
|
border-bottom 1px dotted var(--borderColor)
|
||||||
float left
|
float left
|
||||||
display flex
|
display flex
|
||||||
padding 8px 0
|
padding 8px 0
|
||||||
|
margin 0
|
||||||
|
height 50px
|
||||||
|
width 100%
|
||||||
|
dd
|
||||||
|
font-size 1.1rem
|
||||||
|
color #F17229
|
||||||
|
width 50px
|
||||||
|
text-align center
|
||||||
margin 0
|
margin 0
|
||||||
height 50px
|
line-height 50px
|
||||||
width 100%
|
dt
|
||||||
dd
|
flex 1
|
||||||
font-size 1.1rem
|
display flex
|
||||||
color #F17229
|
a
|
||||||
width 50px
|
color var(--textColor)
|
||||||
text-align center
|
|
||||||
margin 0
|
|
||||||
line-height 50px
|
|
||||||
dt
|
|
||||||
flex 1
|
flex 1
|
||||||
display flex
|
display flex
|
||||||
a
|
height 50px
|
||||||
color var(--textColor)
|
align-items center
|
||||||
flex 1
|
font-weight normal
|
||||||
display flex
|
div
|
||||||
height 50px
|
overflow hidden
|
||||||
align-items center
|
white-space normal
|
||||||
font-weight normal
|
text-overflow ellipsis
|
||||||
div
|
display -webkit-box
|
||||||
overflow hidden
|
-webkit-line-clamp 2
|
||||||
white-space normal
|
-webkit-box-orient vertical
|
||||||
text-overflow ellipsis
|
&:hover
|
||||||
display -webkit-box
|
text-decoration underline
|
||||||
-webkit-line-clamp 2
|
&.more
|
||||||
-webkit-box-orient vertical
|
color $accentColor
|
||||||
&:hover
|
span
|
||||||
text-decoration underline
|
width 50px
|
||||||
&.more
|
margin-right 15px
|
||||||
color $accentColor
|
color #999
|
||||||
span
|
text-align right
|
||||||
width 50px
|
font-size 0.9rem
|
||||||
margin-right 15px
|
line-height 50px
|
||||||
color #999
|
|
||||||
text-align right
|
|
||||||
font-size .9rem
|
|
||||||
line-height 50px
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ export default ({
|
||||||
// 修复ISO8601时间格式为普通时间格式,以及添加作者信息
|
// 修复ISO8601时间格式为普通时间格式,以及添加作者信息
|
||||||
siteData.pages.map(item => {
|
siteData.pages.map(item => {
|
||||||
const { frontmatter: { date, author } } = item
|
const { frontmatter: { date, author } } = item
|
||||||
if (typeof date === 'string' && date.charAt(date.length-1) === 'Z') {
|
if (typeof date === 'string' && date.charAt(date.length - 1) === 'Z') {
|
||||||
item.frontmatter.date = repairUTCDate(date)
|
item.frontmatter.date = repairUTCDate(date)
|
||||||
}
|
}
|
||||||
if (author) {
|
if (author) {
|
||||||
|
|
@ -26,14 +26,14 @@ export default ({
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 修复ISO8601时间格式为普通时间格式
|
// 修复ISO8601时间格式为普通时间格式
|
||||||
function repairUTCDate(date) {
|
function repairUTCDate (date) {
|
||||||
if (!(date instanceof Date)) {
|
if (!(date instanceof Date)) {
|
||||||
date = new Date(date)
|
date = new Date(date)
|
||||||
}
|
}
|
||||||
return `${date.getUTCFullYear()}-${zero(date.getUTCMonth()+1)}-${zero(date.getUTCDate())} ${zero(date.getUTCHours())}:${zero(date.getUTCMinutes())}:${zero(date.getUTCSeconds())}`;
|
return `${date.getUTCFullYear()}-${zero(date.getUTCMonth() + 1)}-${zero(date.getUTCDate())} ${zero(date.getUTCHours())}:${zero(date.getUTCMinutes())}:${zero(date.getUTCSeconds())}`;
|
||||||
}
|
}
|
||||||
// 小于10补0
|
// 小于10补0
|
||||||
function zero(d){
|
function zero (d) {
|
||||||
return d.toString().padStart(2,'0')
|
return d.toString().padStart(2, '0')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ export default {
|
||||||
&.tip, &.green
|
&.tip, &.green
|
||||||
background-color #42b983
|
background-color #42b983
|
||||||
&.error
|
&.error
|
||||||
background-color #DA5961 //#f66
|
background-color #DA5961 // #f66
|
||||||
&.warning, &.warn, &.yellow
|
&.warning, &.warn, &.yellow
|
||||||
background-color darken(#ffe564, 35%)
|
background-color darken(#ffe564, 35%)
|
||||||
& + &
|
& + &
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,28 @@
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const setFrontmatter = require('./node_utils/setFrontmatter')
|
const setFrontmatter = require('./node_utils/setFrontmatter')
|
||||||
const getSidebarData = require('./node_utils/getSidebarData')
|
const getSidebarData = require('./node_utils/getSidebarData')
|
||||||
const {createPage, deletePage} = require('./node_utils/handlePage')
|
const { createPage, deletePage } = require('./node_utils/handlePage')
|
||||||
const chalk = require('chalk') // 命令行打印美化
|
const chalk = require('chalk') // 命令行打印美化
|
||||||
const yaml = require('js-yaml') // yaml转js
|
const yaml = require('js-yaml') // yaml转js
|
||||||
const log = console.log
|
const log = console.log
|
||||||
|
|
||||||
// md容器名
|
// md容器名
|
||||||
const CARD_LIST = 'cardList'
|
const CARD_LIST = 'cardList'
|
||||||
const CARD_IMG_LIST = 'cardImgList'
|
const CARD_IMG_LIST = 'cardImgList'
|
||||||
|
|
||||||
// Theme API.
|
// Theme API.
|
||||||
module.exports = (options, ctx) => {
|
module.exports = (options, ctx) => {
|
||||||
const { sourceDir, themeConfig, siteConfig } = ctx
|
const { sourceDir, themeConfig, siteConfig } = ctx
|
||||||
|
|
||||||
// 自动设置front matter
|
// 自动设置front matter
|
||||||
setFrontmatter(sourceDir, themeConfig)
|
setFrontmatter(sourceDir, themeConfig)
|
||||||
|
|
||||||
// 自动生成结构化侧边栏
|
// 自动生成结构化侧边栏
|
||||||
const sidebar = themeConfig.sidebar
|
const sidebar = themeConfig.sidebar
|
||||||
if(sidebar === 'structuring' || sidebar && sidebar.mode === 'structuring') {
|
if (sidebar === 'structuring' || sidebar && sidebar.mode === 'structuring') {
|
||||||
const collapsable = themeConfig.sidebar.collapsable === false ? false : true
|
const collapsable = themeConfig.sidebar.collapsable === false ? false : true
|
||||||
const sidebarData = getSidebarData(sourceDir, collapsable)
|
const sidebarData = getSidebarData(sourceDir, collapsable)
|
||||||
if(sidebarData) {
|
if (sidebarData) {
|
||||||
themeConfig.sidebar = sidebarData
|
themeConfig.sidebar = sidebarData
|
||||||
log(chalk.blue('tip ') + chalk.green('add sidebar data. 侧边栏数据成功生成。'))
|
log(chalk.blue('tip ') + chalk.green('add sidebar data. 侧边栏数据成功生成。'))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -44,7 +44,7 @@ module.exports = (options, ctx) => {
|
||||||
} else {
|
} else {
|
||||||
deletePage(sourceDir, 'tagsPage')
|
deletePage(sourceDir, 'tagsPage')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 归档页
|
// 归档页
|
||||||
if (themeConfig.archive !== false) {
|
if (themeConfig.archive !== false) {
|
||||||
createPage(sourceDir, 'archivesPage')
|
createPage(sourceDir, 'archivesPage')
|
||||||
|
|
@ -56,8 +56,8 @@ module.exports = (options, ctx) => {
|
||||||
const isAlgoliaSearch = (
|
const isAlgoliaSearch = (
|
||||||
themeConfig.algolia
|
themeConfig.algolia
|
||||||
|| Object
|
|| Object
|
||||||
.keys(siteConfig.locales && themeConfig.locales || {})
|
.keys(siteConfig.locales && themeConfig.locales || {})
|
||||||
.some(base => themeConfig.locales[base].algolia)
|
.some(base => themeConfig.locales[base].algolia)
|
||||||
)
|
)
|
||||||
|
|
||||||
const enableSmoothScroll = themeConfig.smoothScroll === true
|
const enableSmoothScroll = themeConfig.smoothScroll === true
|
||||||
|
|
@ -77,6 +77,13 @@ module.exports = (options, ctx) => {
|
||||||
'@vuepress/plugin-nprogress',
|
'@vuepress/plugin-nprogress',
|
||||||
['smooth-scroll', enableSmoothScroll],
|
['smooth-scroll', enableSmoothScroll],
|
||||||
|
|
||||||
|
['container', {
|
||||||
|
type: 'note',
|
||||||
|
defaultTitle: {
|
||||||
|
'/': '笔记',
|
||||||
|
'/en/': 'NOTE'
|
||||||
|
}
|
||||||
|
}],
|
||||||
['container', {
|
['container', {
|
||||||
type: 'tip',
|
type: 'tip',
|
||||||
defaultTitle: {
|
defaultTitle: {
|
||||||
|
|
@ -129,7 +136,7 @@ module.exports = (options, ctx) => {
|
||||||
'container',
|
'container',
|
||||||
{
|
{
|
||||||
type: CARD_LIST,
|
type: CARD_LIST,
|
||||||
render: (tokens, idx) => {
|
render: (tokens, idx) => {
|
||||||
// tokens 是整个md文件的虚拟dom结构数组
|
// tokens 是整个md文件的虚拟dom结构数组
|
||||||
// idx 是tokens中':::' 所在的索引,而且是当前指定type的':::',分别有开始和结束两次的idx
|
// idx 是tokens中':::' 所在的索引,而且是当前指定type的':::',分别有开始和结束两次的idx
|
||||||
// if (tokens[idx].nesting === 1) { // 开头的 ':::' 标记
|
// if (tokens[idx].nesting === 1) { // 开头的 ':::' 标记
|
||||||
|
|
@ -146,33 +153,33 @@ module.exports = (options, ctx) => {
|
||||||
'container',
|
'container',
|
||||||
{
|
{
|
||||||
type: CARD_IMG_LIST,
|
type: CARD_IMG_LIST,
|
||||||
render: (tokens, idx) => {
|
render: (tokens, idx) => {
|
||||||
return renderCardList(tokens, idx, CARD_IMG_LIST)
|
return renderCardList(tokens, idx, CARD_IMG_LIST)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 渲染md容器的卡片列表
|
// 渲染md容器的卡片列表
|
||||||
function renderCardList(tokens, idx, type) {
|
function renderCardList (tokens, idx, type) {
|
||||||
const END_TYPE = `container_${type}_close`,
|
const END_TYPE = `container_${type}_close`,
|
||||||
_tokens$idx = tokens[idx],
|
_tokens$idx = tokens[idx],
|
||||||
nesting = _tokens$idx.nesting,
|
nesting = _tokens$idx.nesting,
|
||||||
info = _tokens$idx.info;
|
info = _tokens$idx.info;
|
||||||
|
|
||||||
if (nesting === 1) { // 渲染开头的 ':::' 标记
|
if (nesting === 1) { // 渲染开头的 ':::' 标记
|
||||||
let yamlStr = '';
|
let yamlStr = '';
|
||||||
|
|
||||||
for (let i = idx; i < tokens.length; i++) {
|
for (let i = idx; i < tokens.length; i++) {
|
||||||
let _tokens$i = tokens[i],
|
let _tokens$i = tokens[i],
|
||||||
type = _tokens$i.type,
|
type = _tokens$i.type,
|
||||||
content = _tokens$i.content,
|
content = _tokens$i.content,
|
||||||
_info = _tokens$i.info;
|
_info = _tokens$i.info;
|
||||||
if (type === END_TYPE) break; // 遇到结束的 ':::' 时
|
if (type === END_TYPE) break; // 遇到结束的 ':::' 时
|
||||||
if (!content) continue;
|
if (!content) continue;
|
||||||
if (type === 'fence' && _info === 'yaml') { // 是代码块类型,并且是yaml代码
|
if (type === 'fence' && _info === 'yaml') { // 是代码块类型,并且是yaml代码
|
||||||
|
|
@ -188,7 +195,7 @@ function renderCardList(tokens, idx, type) {
|
||||||
dataList = Array.isArray(dataObj) ? dataObj : dataObj.list
|
dataList = Array.isArray(dataObj) ? dataObj : dataObj.list
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataList && dataList.length) { // 有列表数据
|
if (dataList && dataList.length) { // 有列表数据
|
||||||
|
|
||||||
// 每行显示几个
|
// 每行显示几个
|
||||||
let row = Number(info.split(' ').pop())
|
let row = Number(info.split(' ').pop())
|
||||||
|
|
@ -198,12 +205,12 @@ function renderCardList(tokens, idx, type) {
|
||||||
|
|
||||||
let listDOM = ''
|
let listDOM = ''
|
||||||
if (type === CARD_LIST) { // 普通卡片列表
|
if (type === CARD_LIST) { // 普通卡片列表
|
||||||
listDOM = getCardListDOM(dataList, row)
|
listDOM = getCardListDOM(dataList, row)
|
||||||
} else if (type === CARD_IMG_LIST) { // 卡片图片列表
|
} else if (type === CARD_IMG_LIST) { // 卡片图片列表
|
||||||
listDOM = getCardImgListDOM(dataList, row)
|
listDOM = getCardImgListDOM(dataList, row)
|
||||||
}
|
}
|
||||||
|
|
||||||
return `<div class="${type}Container"><div class="card-list">${ listDOM }</div>`
|
return `<div class="${type}Container"><div class="card-list">${listDOM}</div>`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // 渲染':::' 结尾
|
} else { // 渲染':::' 结尾
|
||||||
|
|
@ -213,14 +220,14 @@ function renderCardList(tokens, idx, type) {
|
||||||
|
|
||||||
|
|
||||||
// 将数据解析成DOM结构 - 普通卡片列表
|
// 将数据解析成DOM结构 - 普通卡片列表
|
||||||
function getCardListDOM(dataList, row) {
|
function getCardListDOM (dataList, row) {
|
||||||
let listDOM = ''
|
let listDOM = ''
|
||||||
dataList.forEach(item => {
|
dataList.forEach(item => {
|
||||||
listDOM += `
|
listDOM += `
|
||||||
<${item.link ? 'a href="' + item.link +'" target="_blank"' : 'span' } class="card-item ${ row ? 'row-' + row : '' }"
|
<${item.link ? 'a href="' + item.link + '" target="_blank"' : 'span'} class="card-item ${row ? 'row-' + row : ''}"
|
||||||
style="${ item.bgColor ? 'background-color:' + item.bgColor + ';--randomColor:'+ item.bgColor +';': '--randomColor: var(--bodyBg);' }${ item.textColor ? 'color:' + item.textColor + ';': '' }"
|
style="${item.bgColor ? 'background-color:' + item.bgColor + ';--randomColor:' + item.bgColor + ';' : '--randomColor: var(--bodyBg);'}${item.textColor ? 'color:' + item.textColor + ';' : ''}"
|
||||||
>
|
>
|
||||||
${ item.avatar ? '<img src="'+ item.avatar +'" class="no-zoom">' : '' }
|
${item.avatar ? '<img src="' + item.avatar + '" class="no-zoom">' : ''}
|
||||||
<div>
|
<div>
|
||||||
<p class="name">${item.name}</p>
|
<p class="name">${item.name}</p>
|
||||||
<p class="desc">${item.desc}</p>
|
<p class="desc">${item.desc}</p>
|
||||||
|
|
@ -233,34 +240,27 @@ function getCardListDOM(dataList, row) {
|
||||||
|
|
||||||
|
|
||||||
// 将数据解析成DOM结构 - 图文卡片列表
|
// 将数据解析成DOM结构 - 图文卡片列表
|
||||||
function getCardImgListDOM(dataList, row) {
|
function getCardImgListDOM (dataList, row) {
|
||||||
let listDOM = ''
|
let listDOM = ''
|
||||||
dataList.forEach(item => {
|
dataList.forEach(item => {
|
||||||
listDOM += `
|
listDOM += `
|
||||||
<div class="card-item ${ row ? 'row-' + row : '' }" >
|
<div class="card-item ${row ? 'row-' + row : ''}" >
|
||||||
<div class="box-img">
|
<a href="${item.link}" target="_blank">
|
||||||
<a href="${item.link}" target="_blank">
|
<div class="box-img">
|
||||||
<img src="${item.img}" class="no-zoom">
|
<img src="${item.img}" class="no-zoom">
|
||||||
</a>
|
</div>
|
||||||
</div>
|
<div class="box-info">
|
||||||
<div class="box-info">
|
<p class="name">${item.name}</p>
|
||||||
<a href="${item.link}" target="_blank">
|
${item.desc ? `<p class="desc">${item.desc}</p>` : ''}
|
||||||
<p class="name">${item.name}</p>
|
</div>
|
||||||
${item.desc ? `<p class="desc">${item.desc}</p>` : ''}
|
|
||||||
</a>
|
${item.avatar || item.author ? `<div class="box-footer">
|
||||||
</div>
|
${item.avatar ? `<img src="${item.avatar}" class="no-zoom">` : ''}
|
||||||
|
${item.author ? `<span>${item.author}</span>` : ''}
|
||||||
${item.avatar || item.author
|
</div>`: ''}
|
||||||
? `<div class="box-footer">
|
</a>
|
||||||
<a href="${item.link}" target="_blank">
|
|
||||||
${item.avatar ? `<img src="${item.avatar}" class="no-zoom">` : ''}
|
|
||||||
${item.author ? `<span>${item.author}</span>` : ''}
|
|
||||||
</a>
|
|
||||||
</div>`
|
|
||||||
: ''
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
return listDOM
|
return listDOM
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,18 +29,18 @@
|
||||||
#bottom
|
#bottom
|
||||||
/>
|
/>
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
|
|
||||||
<!-- 首页 -->
|
<!-- 首页 -->
|
||||||
<Home v-if="$page.frontmatter.home"/>
|
<Home v-if="$page.frontmatter.home" />
|
||||||
|
|
||||||
<!-- 分类页 -->
|
<!-- 分类页 -->
|
||||||
<CategoriesPage v-else-if="$page.frontmatter.categoriesPage"/>
|
<CategoriesPage v-else-if="$page.frontmatter.categoriesPage" />
|
||||||
|
|
||||||
<!-- 标签页 -->
|
<!-- 标签页 -->
|
||||||
<TagsPage v-else-if="$page.frontmatter.tagsPage"/>
|
<TagsPage v-else-if="$page.frontmatter.tagsPage" />
|
||||||
|
|
||||||
<!-- 归档页 -->
|
<!-- 归档页 -->
|
||||||
<ArchivesPage v-else-if="$page.frontmatter.archivesPage"/>
|
<ArchivesPage v-else-if="$page.frontmatter.archivesPage" />
|
||||||
|
|
||||||
<!-- 文章页或其他页 -->
|
<!-- 文章页或其他页 -->
|
||||||
<Page
|
<Page
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|
||||||
<Buttons
|
<Buttons
|
||||||
ref="buttons"
|
ref="buttons"
|
||||||
@toggle-theme-mode="toggleThemeMode"
|
@toggle-theme-mode="toggleThemeMode"
|
||||||
/>
|
/>
|
||||||
|
|
@ -97,10 +97,10 @@ export default {
|
||||||
themeMode: 'light'
|
themeMode: 'light'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount(){
|
beforeMount () {
|
||||||
// 引入图标库
|
// 引入图标库
|
||||||
const social = this.$themeConfig.social
|
const social = this.$themeConfig.social
|
||||||
if(social && social.iconfontCssFile ) {
|
if (social && social.iconfontCssFile) {
|
||||||
let linkElm = document.createElement("link")
|
let linkElm = document.createElement("link")
|
||||||
linkElm.setAttribute('rel', 'stylesheet');
|
linkElm.setAttribute('rel', 'stylesheet');
|
||||||
linkElm.setAttribute("type", "text/css")
|
linkElm.setAttribute("type", "text/css")
|
||||||
|
|
@ -109,7 +109,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
showRightMenu() {
|
showRightMenu () {
|
||||||
const { headers } = this.$page
|
const { headers } = this.$page
|
||||||
return (
|
return (
|
||||||
!this.$frontmatter.home
|
!this.$frontmatter.home
|
||||||
|
|
@ -169,16 +169,16 @@ export default {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created () {
|
||||||
const sidebarOpen = this.$themeConfig.sidebarOpen
|
const sidebarOpen = this.$themeConfig.sidebarOpen
|
||||||
if (sidebarOpen === false) {
|
if (sidebarOpen === false) {
|
||||||
this.isSidebarOpen = sidebarOpen
|
this.isSidebarOpen = sidebarOpen
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount () {
|
||||||
this.isSidebarOpenOfclientWidth()
|
this.isSidebarOpenOfclientWidth()
|
||||||
const mode = storage.get('mode') // 不放在created是因为vuepress不能在created访问浏览器api,如window
|
const mode = storage.get('mode') // 不放在created是因为vuepress不能在created访问浏览器api,如window
|
||||||
if(!mode || mode === 'auto') { // 当未切换过模式,或模式处于'跟随系统'时
|
if (!mode || mode === 'auto') { // 当未切换过模式,或模式处于'跟随系统'时
|
||||||
this._autoMode()
|
this._autoMode()
|
||||||
} else {
|
} else {
|
||||||
this.themeMode = mode
|
this.themeMode = mode
|
||||||
|
|
@ -196,7 +196,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解决移动端初始化页面时侧边栏闪现的问题
|
// 解决移动端初始化页面时侧边栏闪现的问题
|
||||||
this.showSidebar = true
|
this.showSidebar = true
|
||||||
this.$router.afterEach(() => {
|
this.$router.afterEach(() => {
|
||||||
this.isSidebarOpenOfclientWidth()
|
this.isSidebarOpenOfclientWidth()
|
||||||
})
|
})
|
||||||
|
|
@ -204,30 +204,30 @@ export default {
|
||||||
// 向下滚动收起导航栏
|
// 向下滚动收起导航栏
|
||||||
let p = 0, t = 0;
|
let p = 0, t = 0;
|
||||||
window.addEventListener('scroll', _.throttle(() => {
|
window.addEventListener('scroll', _.throttle(() => {
|
||||||
if(!this.isSidebarOpen) { // 侧边栏关闭时
|
if (!this.isSidebarOpen) { // 侧边栏关闭时
|
||||||
p = this.getScrollTop()
|
p = this.getScrollTop()
|
||||||
if(t < p && p > NAVBAR_HEIGHT) { // 向下滚动
|
if (t < p && p > NAVBAR_HEIGHT) { // 向下滚动
|
||||||
this.hideNavbar = true
|
this.hideNavbar = true
|
||||||
} else { // 向上
|
} else { // 向上
|
||||||
this.hideNavbar = false
|
this.hideNavbar = false
|
||||||
}
|
}
|
||||||
setTimeout(() => {t = p},0)
|
setTimeout(() => { t = p }, 0)
|
||||||
}
|
}
|
||||||
}, 300))
|
}, 300))
|
||||||
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
isSidebarOpen() {
|
isSidebarOpen () {
|
||||||
if(this.isSidebarOpen) { // 侧边栏打开时,恢复导航栏显示
|
if (this.isSidebarOpen) { // 侧边栏打开时,恢复导航栏显示
|
||||||
this.hideNavbar = false
|
this.hideNavbar = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
themeMode() {
|
themeMode () {
|
||||||
this.setBodyClass()
|
this.setBodyClass()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setBodyClass() {
|
setBodyClass () {
|
||||||
document.body.className = 'theme-mode-' + this.themeMode
|
document.body.className = 'theme-mode-' + this.themeMode
|
||||||
},
|
},
|
||||||
getScrollTop () {
|
getScrollTop () {
|
||||||
|
|
@ -235,7 +235,7 @@ export default {
|
||||||
|| document.documentElement.scrollTop
|
|| document.documentElement.scrollTop
|
||||||
|| document.body.scrollTop || 0
|
|| document.body.scrollTop || 0
|
||||||
},
|
},
|
||||||
isSidebarOpenOfclientWidth() {
|
isSidebarOpenOfclientWidth () {
|
||||||
if (document.documentElement.clientWidth < MOBILE_DESKTOP_BREAKPOINT) {
|
if (document.documentElement.clientWidth < MOBILE_DESKTOP_BREAKPOINT) {
|
||||||
this.isSidebarOpen = false
|
this.isSidebarOpen = false
|
||||||
}
|
}
|
||||||
|
|
@ -245,21 +245,21 @@ export default {
|
||||||
this.$emit('toggle-sidebar', this.isSidebarOpen)
|
this.$emit('toggle-sidebar', this.isSidebarOpen)
|
||||||
},
|
},
|
||||||
_autoMode () {
|
_autoMode () {
|
||||||
if(window.matchMedia('(prefers-color-scheme: dark)').matches){ // 系统处于深色模式
|
if (window.matchMedia('(prefers-color-scheme: dark)').matches) { // 系统处于深色模式
|
||||||
this.themeMode = 'dark'
|
this.themeMode = 'dark'
|
||||||
} else {
|
} else {
|
||||||
this.themeMode = 'light'
|
this.themeMode = 'light'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toggleThemeMode (key) {
|
toggleThemeMode (key) {
|
||||||
if(key === 'auto') {
|
if (key === 'auto') {
|
||||||
this._autoMode()
|
this._autoMode()
|
||||||
} else {
|
} else {
|
||||||
this.themeMode = key
|
this.themeMode = key
|
||||||
}
|
}
|
||||||
storage.set('mode', key)
|
storage.set('mode', key)
|
||||||
},
|
},
|
||||||
|
|
||||||
// side swipe
|
// side swipe
|
||||||
onTouchStart (e) {
|
onTouchStart (e) {
|
||||||
this.touchStart = {
|
this.touchStart = {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
export default {
|
|
||||||
methods: {
|
|
||||||
encodeUrl(str) {
|
|
||||||
str = str + ''
|
|
||||||
str = str.replace(/ |((?=[\x21-\x7e]+)[^A-Za-z0-9])/g, '-')
|
|
||||||
return str
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,20 +2,20 @@ import { filterPosts, sortPosts, sortPostsByDate, groupPosts, categoriesAndTags
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
$filterPosts() { // 过滤非文章页和首页的文章数据
|
$filterPosts () { // 过滤非文章页和首页的文章数据
|
||||||
return filterPosts(this.$site.pages)
|
return filterPosts(this.$site.pages)
|
||||||
},
|
},
|
||||||
$sortPosts() { // 按置顶和时间排序的文章数据
|
$sortPosts () { // 按置顶和时间排序的文章数据
|
||||||
return sortPosts(this.$filterPosts)
|
return sortPosts(this.$filterPosts)
|
||||||
},
|
},
|
||||||
$sortPostsByDate() { // 仅按时间排序的文章数据
|
$sortPostsByDate () { // 仅按时间排序的文章数据
|
||||||
return sortPostsByDate(this.$filterPosts)
|
return sortPostsByDate(this.$filterPosts)
|
||||||
},
|
},
|
||||||
$groupPosts() { // 按分类和标签分组的文章数据
|
$groupPosts () { // 按分类和标签分组的文章数据
|
||||||
return groupPosts(this.$sortPosts)
|
return groupPosts(this.$sortPosts)
|
||||||
},
|
},
|
||||||
$categoriesAndTags() { // 所有分类和标签数据
|
$categoriesAndTags () { // 所有分类和标签数据
|
||||||
return categoriesAndTags(this.$groupPosts)
|
return categoriesAndTags(this.$groupPosts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data () {
|
||||||
return {
|
return {
|
||||||
badges: [
|
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,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',
|
||||||
|
|
@ -9,20 +9,20 @@ export default {
|
||||||
currentBadge: ''
|
currentBadge: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created () {
|
||||||
if (this.$themeConfig.titleBadgeIcons) {
|
if (this.$themeConfig.titleBadgeIcons) {
|
||||||
this.badges = this.$themeConfig.titleBadgeIcons
|
this.badges = this.$themeConfig.titleBadgeIcons
|
||||||
}
|
}
|
||||||
this.currentBadge = this.getBadge()
|
this.currentBadge = this.getBadge()
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route.path'() {
|
'$route.path' () {
|
||||||
this.currentBadge = this.getBadge()
|
this.currentBadge = this.getBadge()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getBadge() {
|
getBadge () {
|
||||||
return this.badges[Math.floor(Math.random() * this.badges.length)]
|
return this.badges[Math.floor(Math.random() * this.badges.length)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,14 @@ let catalogueData = {}; // 目录页数据
|
||||||
* @param {String} sourceDir .md文件所在源目录(一般是docs目录)
|
* @param {String} sourceDir .md文件所在源目录(一般是docs目录)
|
||||||
* @param {Boolean} collapsable 是否可折叠
|
* @param {Boolean} collapsable 是否可折叠
|
||||||
*/
|
*/
|
||||||
function createSidebarData(sourceDir, collapsable){
|
function createSidebarData (sourceDir, collapsable) {
|
||||||
const sidebarData = {};
|
const sidebarData = {};
|
||||||
const tocs = readTocs(sourceDir);
|
const tocs = readTocs(sourceDir);
|
||||||
tocs.forEach(toc => { // toc是每个目录的绝对路径
|
tocs.forEach(toc => { // toc是每个目录的绝对路径
|
||||||
|
|
||||||
const tocArr = toc.split('\\')
|
const tocArr = toc.split('\\')
|
||||||
if (tocArr[tocArr.length -1] === '_posts') { // 碎片化文章
|
if (tocArr[tocArr.length - 1] === '_posts') { // 碎片化文章
|
||||||
|
|
||||||
// 注释说明:碎片化文章不需要生成结构化侧边栏 2020.05.01
|
// 注释说明:碎片化文章不需要生成结构化侧边栏 2020.05.01
|
||||||
// const sidebarArr = mapTocToPostSidebar(toc);
|
// const sidebarArr = mapTocToPostSidebar(toc);
|
||||||
// sidebarData[`/${path.basename(toc)}/`] = sidebarArr
|
// sidebarData[`/${path.basename(toc)}/`] = sidebarArr
|
||||||
|
|
@ -44,7 +44,7 @@ module.exports = createSidebarData;
|
||||||
* 读取指定目录下的文件绝对路径
|
* 读取指定目录下的文件绝对路径
|
||||||
* @param {String} root 指定的目录
|
* @param {String} root 指定的目录
|
||||||
*/
|
*/
|
||||||
function readTocs(root){
|
function readTocs (root) {
|
||||||
const result = [];
|
const result = [];
|
||||||
const files = fs.readdirSync(root); // 读取目录,返回数组,成员是root底下所有的目录名 (包含文件夹和文件)
|
const files = fs.readdirSync(root); // 读取目录,返回数组,成员是root底下所有的目录名 (包含文件夹和文件)
|
||||||
files.forEach(name => {
|
files.forEach(name => {
|
||||||
|
|
@ -59,9 +59,9 @@ function readTocs(root){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将碎片化文章目录(_posts)映射为对应的侧边栏配置数据
|
* 将碎片化文章目录(_posts)映射为对应的侧边栏配置数据
|
||||||
* @param {String} root
|
* @param {String} root
|
||||||
*/
|
*/
|
||||||
function mapTocToPostSidebar(root){
|
function mapTocToPostSidebar (root) {
|
||||||
let postSidebar = [] // 碎片化文章数据
|
let postSidebar = [] // 碎片化文章数据
|
||||||
const files = fs.readdirSync(root); // 读取目录(文件和文件夹),返回数组
|
const files = fs.readdirSync(root); // 读取目录(文件和文件夹),返回数组
|
||||||
|
|
||||||
|
|
@ -74,10 +74,10 @@ function mapTocToPostSidebar(root){
|
||||||
log(chalk.yellow(`warning: 该文件 "${file}" 在_posts文件夹中,不应有序号,且文件名中间不应有'.'`))
|
log(chalk.yellow(`warning: 该文件 "${file}" 在_posts文件夹中,不应有序号,且文件名中间不应有'.'`))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if(stat.isDirectory()){ // 是文件夹目录
|
if (stat.isDirectory()) { // 是文件夹目录
|
||||||
// log(chalk.yellow(`warning: 该目录 "${file}" 内文件无法生成侧边栏,_posts文件夹里面不能有二级目录。`))
|
// log(chalk.yellow(`warning: 该目录 "${file}" 内文件无法生成侧边栏,_posts文件夹里面不能有二级目录。`))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let [title, type] = filename.split('.');
|
let [title, type] = filename.split('.');
|
||||||
if (type !== 'md') {
|
if (type !== 'md') {
|
||||||
|
|
@ -88,7 +88,7 @@ function mapTocToPostSidebar(root){
|
||||||
const contentStr = fs.readFileSync(file, 'utf8') // 读取md文件内容,返回字符串
|
const contentStr = fs.readFileSync(file, 'utf8') // 读取md文件内容,返回字符串
|
||||||
const { data } = matter(contentStr) // 解析出front matter数据
|
const { data } = matter(contentStr) // 解析出front matter数据
|
||||||
const permalink = data.permalink || ''
|
const permalink = data.permalink || ''
|
||||||
postSidebar.push([filename, title, permalink ]); // [<路径>, <文件标题>, <永久链接>]
|
postSidebar.push([filename, title, permalink]); // [<路径>, <文件标题>, <永久链接>]
|
||||||
})
|
})
|
||||||
|
|
||||||
return postSidebar
|
return postSidebar
|
||||||
|
|
@ -97,12 +97,12 @@ function mapTocToPostSidebar(root){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将目录映射为对应的侧边栏配置数据
|
* 将目录映射为对应的侧边栏配置数据
|
||||||
* @param {String} root
|
* @param {String} root
|
||||||
* @param {Boolean} collapsable
|
* @param {Boolean} collapsable
|
||||||
* @param {String} prefix
|
* @param {String} prefix
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function mapTocToSidebar(root, collapsable, prefix){
|
function mapTocToSidebar (root, collapsable, prefix) {
|
||||||
prefix = prefix || '';
|
prefix = prefix || '';
|
||||||
let sidebar = [];
|
let sidebar = [];
|
||||||
const files = fs.readdirSync(root); // 读取目录(文件和文件夹),返回数组
|
const files = fs.readdirSync(root); // 读取目录(文件和文件夹),返回数组
|
||||||
|
|
@ -119,7 +119,7 @@ function mapTocToSidebar(root, collapsable, prefix){
|
||||||
if (sidebar[order]) { // 判断序号是否已经存在
|
if (sidebar[order]) { // 判断序号是否已经存在
|
||||||
log(chalk.yellow(`warning: 该文件 "${file}" 的序号在同一级别中重复出现,将会被覆盖`))
|
log(chalk.yellow(`warning: 该文件 "${file}" 的序号在同一级别中重复出现,将会被覆盖`))
|
||||||
}
|
}
|
||||||
if(stat.isDirectory()){ // 是文件夹目录
|
if (stat.isDirectory()) { // 是文件夹目录
|
||||||
sidebar[order] = {
|
sidebar[order] = {
|
||||||
title,
|
title,
|
||||||
collapsable, // 是否可折叠,默认true
|
collapsable, // 是否可折叠,默认true
|
||||||
|
|
@ -133,7 +133,7 @@ function mapTocToSidebar(root, collapsable, prefix){
|
||||||
const contentStr = fs.readFileSync(file, 'utf8') // 读取md文件内容,返回字符串
|
const contentStr = fs.readFileSync(file, 'utf8') // 读取md文件内容,返回字符串
|
||||||
const { data } = matter(contentStr) // 解析出front matter数据
|
const { data } = matter(contentStr) // 解析出front matter数据
|
||||||
const permalink = data.permalink || ''
|
const permalink = data.permalink || ''
|
||||||
sidebar[order] = [prefix + filename, title, permalink ]; // [<路径>, <文件标题>, <永久链接>]
|
sidebar[order] = [prefix + filename, title, permalink]; // [<路径>, <文件标题>, <永久链接>]
|
||||||
|
|
||||||
// 目录页和永久链接,用于给面包屑提供数据
|
// 目录页和永久链接,用于给面包屑提供数据
|
||||||
const pageComponent = data.pageComponent
|
const pageComponent = data.pageComponent
|
||||||
|
|
@ -148,4 +148,4 @@ function mapTocToSidebar(root, collapsable, prefix){
|
||||||
sidebar,
|
sidebar,
|
||||||
catalogueData
|
catalogueData
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ const chalk = require('chalk') // 命令行打印美化
|
||||||
const { type } = require('./modules/fn');
|
const { type } = require('./modules/fn');
|
||||||
const log = console.log
|
const log = console.log
|
||||||
|
|
||||||
function createPage(sourceDir, page) {
|
function createPage (sourceDir, page) {
|
||||||
const dirPath = path.join(sourceDir, '@pages') // 生成的文件夹路径
|
const dirPath = path.join(sourceDir, '@pages') // 生成的文件夹路径
|
||||||
|
|
||||||
// 文件夹不存在时
|
// 文件夹不存在时
|
||||||
|
|
@ -21,30 +21,30 @@ function createPage(sourceDir, page) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 注意:反引号字符串的格式会映射到文件
|
// 注意:反引号字符串的格式会映射到文件
|
||||||
let content = ''
|
let content = ''
|
||||||
if (page.indexOf('categories') > -1) {
|
if (page.indexOf('categories') > -1) {
|
||||||
content = `---
|
content = `---
|
||||||
categoriesPage: true
|
categoriesPage: true
|
||||||
title: 分类
|
title: 分类
|
||||||
permalink: /categories/
|
permalink: /categories/
|
||||||
article: false
|
article: false
|
||||||
---`
|
---`
|
||||||
} else if (page.indexOf('tags') > -1){
|
} else if (page.indexOf('tags') > -1) {
|
||||||
content = `---
|
content = `---
|
||||||
tagsPage: true
|
tagsPage: true
|
||||||
title: 标签
|
title: 标签
|
||||||
permalink: /tags/
|
permalink: /tags/
|
||||||
article: false
|
article: false
|
||||||
---`
|
---`
|
||||||
} else if (page.indexOf('archives') > -1){
|
} else if (page.indexOf('archives') > -1) {
|
||||||
content = `---
|
content = `---
|
||||||
archivesPage: true
|
archivesPage: true
|
||||||
title: 归档
|
title: 归档
|
||||||
permalink: /archives/
|
permalink: /archives/
|
||||||
article: false
|
article: false
|
||||||
---`
|
---`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (content) {
|
if (content) {
|
||||||
fs.writeFileSync(pagePath, content)
|
fs.writeFileSync(pagePath, content)
|
||||||
|
|
@ -53,7 +53,7 @@ article: false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除页面文件
|
// 删除页面文件
|
||||||
function deletePage(sourceDir, page) {
|
function deletePage (sourceDir, page) {
|
||||||
const dirPath = path.join(sourceDir, '@pages') // 文件夹路径
|
const dirPath = path.join(sourceDir, '@pages') // 文件夹路径
|
||||||
const pagePath = path.join(dirPath, `${page}.md`) // 文件路径
|
const pagePath = path.join(dirPath, `${page}.md`) // 文件路径
|
||||||
|
|
||||||
|
|
@ -66,10 +66,10 @@ function deletePage(sourceDir, page) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除文件夹
|
// 删除文件夹
|
||||||
function deleteDir(dirPath) {
|
function deleteDir (dirPath) {
|
||||||
if (fs.existsSync(dirPath)) {
|
if (fs.existsSync(dirPath)) {
|
||||||
const files = fs.readdirSync(dirPath)
|
const files = fs.readdirSync(dirPath)
|
||||||
if( type(files) === 'array' && files.length === 0) {
|
if (type(files) === 'array' && files.length === 0) {
|
||||||
fs.rmdirSync(dirPath)
|
fs.rmdirSync(dirPath)
|
||||||
log(chalk.blue('tip ') + chalk.green(`delete dir(删除目录): ${dirPath}`))
|
log(chalk.blue('tip ') + chalk.green(`delete dir(删除目录): ${dirPath}`))
|
||||||
}
|
}
|
||||||
|
|
@ -79,4 +79,4 @@ function deleteDir(dirPath) {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createPage,
|
createPage,
|
||||||
deletePage
|
deletePage
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
// 类型判断
|
// 类型判断
|
||||||
exports.type = function (o){
|
exports.type = function (o) {
|
||||||
var s = Object.prototype.toString.call(o)
|
var s = Object.prototype.toString.call(o)
|
||||||
return s.match(/\[object (.*?)\]/)[1].toLowerCase()
|
return s.match(/\[object (.*?)\]/)[1].toLowerCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修复date时区格式的问题
|
// 修复date时区格式的问题
|
||||||
exports.repairDate = function (date) {
|
exports.repairDate = function (date) {
|
||||||
date = new Date(date);
|
date = new Date(date);
|
||||||
return `${date.getUTCFullYear()}-${zero(date.getUTCMonth()+1)}-${zero(date.getUTCDate())} ${zero(date.getUTCHours())}:${zero(date.getUTCMinutes())}:${zero(date.getUTCSeconds())}`;
|
return `${date.getUTCFullYear()}-${zero(date.getUTCMonth() + 1)}-${zero(date.getUTCDate())} ${zero(date.getUTCHours())}:${zero(date.getUTCMinutes())}:${zero(date.getUTCSeconds())}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 日期的格式
|
// 日期的格式
|
||||||
exports.dateFormat = function (date) {
|
exports.dateFormat = function (date) {
|
||||||
return `${date.getFullYear()}-${zero(date.getMonth()+1)}-${zero(date.getDate())} ${zero(date.getHours())}:${zero(date.getMinutes())}:${zero(date.getSeconds())}`
|
return `${date.getFullYear()}-${zero(date.getMonth() + 1)}-${zero(date.getDate())} ${zero(date.getHours())}:${zero(date.getMinutes())}:${zero(date.getSeconds())}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 小于10补0
|
// 小于10补0
|
||||||
function zero(d){
|
function zero (d) {
|
||||||
return d.toString().padStart(2,'0')
|
return d.toString().padStart(2, '0')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,38 +6,38 @@ const path = require('path'); // 路径模块
|
||||||
const chalk = require('chalk') // 命令行打印美化
|
const chalk = require('chalk') // 命令行打印美化
|
||||||
const log = console.log
|
const log = console.log
|
||||||
|
|
||||||
function readFileList(dir, filesList = []) {
|
function readFileList (dir, filesList = []) {
|
||||||
const files = fs.readdirSync(dir);
|
const files = fs.readdirSync(dir);
|
||||||
files.forEach( (item, index) => {
|
files.forEach((item, index) => {
|
||||||
let filePath = path.join(dir, item);
|
let filePath = path.join(dir, item);
|
||||||
const stat = fs.statSync(filePath);
|
const stat = fs.statSync(filePath);
|
||||||
if (stat.isDirectory() && item !== '.vuepress' && item !== '@pages') {
|
if (stat.isDirectory() && item !== '.vuepress' && item !== '@pages') {
|
||||||
readFileList(path.join(dir, item), filesList); //递归读取文件
|
readFileList(path.join(dir, item), filesList); //递归读取文件
|
||||||
} else {
|
} else {
|
||||||
if(path.basename(dir) !== 'docs'){ // 过滤docs目录级下的文件
|
if (path.basename(dir) !== 'docs') { // 过滤docs目录级下的文件
|
||||||
|
|
||||||
const fileNameArr = path.basename(filePath).split('.')
|
const fileNameArr = path.basename(filePath).split('.')
|
||||||
let name = null, type = null;
|
let name = null, type = null;
|
||||||
if (fileNameArr.length === 2) { // 没有序号的文件
|
if (fileNameArr.length === 2) { // 没有序号的文件
|
||||||
name = fileNameArr[0]
|
name = fileNameArr[0]
|
||||||
type = fileNameArr[1]
|
type = fileNameArr[1]
|
||||||
} else if (fileNameArr.length === 3) { // 有序号的文件
|
} else if (fileNameArr.length === 3) { // 有序号的文件
|
||||||
name = fileNameArr[1]
|
name = fileNameArr[1]
|
||||||
type = fileNameArr[2]
|
type = fileNameArr[2]
|
||||||
} else { // 超过两个‘.’的
|
} else { // 超过两个‘.’的
|
||||||
log(chalk.yellow(`warning: 该文件 "${filePath}" 没有按照约定命名,将忽略生成相应数据。`))
|
log(chalk.yellow(`warning: 该文件 "${filePath}" 没有按照约定命名,将忽略生成相应数据。`))
|
||||||
return
|
return
|
||||||
}
|
|
||||||
if(type === 'md'){ // 过滤非md文件
|
|
||||||
filesList.push({
|
|
||||||
name,
|
|
||||||
filePath
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
if (type === 'md') { // 过滤非md文件
|
||||||
|
filesList.push({
|
||||||
|
name,
|
||||||
|
filePath
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return filesList;
|
return filesList;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = readFileList;
|
module.exports = readFileList;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ const jsonToYaml = require('json2yaml')
|
||||||
const chalk = require('chalk') // 命令行打印美化
|
const chalk = require('chalk') // 命令行打印美化
|
||||||
// const arg = process.argv.splice(2)[0]; // 获取命令行传入的参数
|
// const arg = process.argv.splice(2)[0]; // 获取命令行传入的参数
|
||||||
const readFileList = require('./modules/readFileList');
|
const readFileList = require('./modules/readFileList');
|
||||||
const { type, repairDate, dateFormat} = require('./modules/fn');
|
const { type, repairDate, dateFormat } = require('./modules/fn');
|
||||||
const log = console.log
|
const log = console.log
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@ const PREFIX = '/pages/'
|
||||||
/**
|
/**
|
||||||
* 给.md文件设置frontmatter(标题、日期、永久链接等数据)
|
* 给.md文件设置frontmatter(标题、日期、永久链接等数据)
|
||||||
*/
|
*/
|
||||||
function setFrontmatter(sourceDir, themeConfig) {
|
function setFrontmatter (sourceDir, themeConfig) {
|
||||||
|
|
||||||
const isCategory = themeConfig.category
|
const isCategory = themeConfig.category
|
||||||
const isTag = themeConfig.tag
|
const isTag = themeConfig.tag
|
||||||
|
|
@ -33,16 +33,16 @@ function setFrontmatter(sourceDir, themeConfig) {
|
||||||
const dateStr = dateFormat(getBirthtime(stat));// 文件的创建时间
|
const dateStr = dateFormat(getBirthtime(stat));// 文件的创建时间
|
||||||
const categories = getCategories(file, categoryText)
|
const categories = getCategories(file, categoryText)
|
||||||
|
|
||||||
// 注意下面这些反引号字符串的格式会映射到文件
|
// 注意下面这些反引号字符串的格式会映射到文件
|
||||||
const cateStr = isCategory === false ? '' : `
|
const cateStr = isCategory === false ? '' : `
|
||||||
categories:
|
categories:
|
||||||
- ${categories[0]}${categories[1] ? '\r\n - '+ categories[1] : ''}`;
|
- ${categories[0]}${categories[1] ? '\r\n - ' + categories[1] : ''}`;
|
||||||
|
|
||||||
const tagsStr = isTag === false ? '' : `
|
const tagsStr = isTag === false ? '' : `
|
||||||
tags:
|
tags:
|
||||||
- `;
|
- `;
|
||||||
|
|
||||||
const fmData = `---
|
const fmData = `---
|
||||||
title: ${file.name}
|
title: ${file.name}
|
||||||
date: ${dateStr}
|
date: ${dateStr}
|
||||||
permalink: ${getPermalink()}${file.filePath.indexOf('_posts') > -1 ? '\r\nsidebar: auto' : ''}${cateStr}${tagsStr}
|
permalink: ${getPermalink()}${file.filePath.indexOf('_posts') > -1 ? '\r\nsidebar: auto' : ''}${cateStr}${tagsStr}
|
||||||
|
|
@ -71,18 +71,18 @@ permalink: ${getPermalink()}${file.filePath.indexOf('_posts') > -1 ? '\r\nsideba
|
||||||
matterData.permalink = getPermalink();
|
matterData.permalink = getPermalink();
|
||||||
mark = true;
|
mark = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file.filePath.indexOf('_posts') > -1 && !matterData.hasOwnProperty('sidebar')) { // auto侧边栏,_posts文件夹特有
|
if (file.filePath.indexOf('_posts') > -1 && !matterData.hasOwnProperty('sidebar')) { // auto侧边栏,_posts文件夹特有
|
||||||
matterData.sidebar = "auto";
|
matterData.sidebar = "auto";
|
||||||
mark = true;
|
mark = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !matterData.hasOwnProperty('pageComponent') && matterData.article !== false ) { // 是文章页才添加分类和标签
|
if (!matterData.hasOwnProperty('pageComponent') && matterData.article !== false) { // 是文章页才添加分类和标签
|
||||||
if (isCategory !== false && !matterData.hasOwnProperty('categories')) { // 分类
|
if (isCategory !== false && !matterData.hasOwnProperty('categories')) { // 分类
|
||||||
matterData.categories = getCategories(file, categoryText)
|
matterData.categories = getCategories(file, categoryText)
|
||||||
mark = true;
|
mark = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTag !== false && !matterData.hasOwnProperty('tags')) { // 标签
|
if (isTag !== false && !matterData.hasOwnProperty('tags')) { // 标签
|
||||||
matterData.tags = [''];
|
matterData.tags = [''];
|
||||||
mark = true;
|
mark = true;
|
||||||
|
|
@ -90,20 +90,20 @@ permalink: ${getPermalink()}${file.filePath.indexOf('_posts') > -1 ? '\r\nsideba
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mark) {
|
if (mark) {
|
||||||
if(matterData.date && type(matterData.date) === 'date') {
|
if (matterData.date && type(matterData.date) === 'date') {
|
||||||
matterData.date = repairDate(matterData.date) // 修复时间格式
|
matterData.date = repairDate(matterData.date) // 修复时间格式
|
||||||
}
|
}
|
||||||
const newData = jsonToYaml.stringify(matterData).replace(/\n\s{2}/g,"\n").replace(/"/g,"") + '---\r\n' + fileMatterObj.content;
|
const newData = jsonToYaml.stringify(matterData).replace(/\n\s{2}/g, "\n").replace(/"/g, "") + '---\r\n' + fileMatterObj.content;
|
||||||
fs.writeFileSync(file.filePath, newData); // 写入
|
fs.writeFileSync(file.filePath, newData); // 写入
|
||||||
log(chalk.blue('tip ') + chalk.green(`write frontmatter(写入frontmatter):${file.filePath} `))
|
log(chalk.blue('tip ') + chalk.green(`write frontmatter(写入frontmatter):${file.filePath} `))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取分类数据
|
// 获取分类数据
|
||||||
function getCategories(file, categoryText) {
|
function getCategories (file, categoryText) {
|
||||||
let categories = []
|
let categories = []
|
||||||
|
|
||||||
if (file.filePath.indexOf('_posts') === -1) { // 不在_posts文件夹
|
if (file.filePath.indexOf('_posts') === -1) { // 不在_posts文件夹
|
||||||
|
|
@ -120,13 +120,13 @@ function getCategories(file, categoryText) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取文件创建时间
|
// 获取文件创建时间
|
||||||
function getBirthtime(stat){
|
function getBirthtime (stat) {
|
||||||
// 在一些系统下无法获取birthtime属性的正确时间,使用atime代替
|
// 在一些系统下无法获取birthtime属性的正确时间,使用atime代替
|
||||||
return stat.birthtime.getFullYear() != 1970 ? stat.birthtime : stat.atime
|
return stat.birthtime.getFullYear() != 1970 ? stat.birthtime : stat.atime
|
||||||
}
|
}
|
||||||
|
|
||||||
// 定义永久链接数据
|
// 定义永久链接数据
|
||||||
function getPermalink() {
|
function getPermalink () {
|
||||||
return `${PREFIX + (Math.random() + Math.random()).toString(16).slice(2, 8)}/`
|
return `${PREFIX + (Math.random() + Math.random()).toString(16).slice(2, 8)}/`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "vuepress-theme-vdoing",
|
"name": "vuepress-theme-vdoing",
|
||||||
"version": "1.4.4",
|
"version": "1.5.0",
|
||||||
"description": "Vdoing theme for VuePress. 一个基于VuePress的知识管理兼博客主题。",
|
"description": "Vdoing theme for VuePress. 一个基于VuePress的知识管理兼博客主题。",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "gaoyi(Evan) Xu"
|
"name": "gaoyi(Evan) Xu"
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
"@vuepress/plugin-active-header-links": "^1.2.0",
|
"@vuepress/plugin-active-header-links": "^1.2.0",
|
||||||
"@vuepress/plugin-nprogress": "^1.2.0",
|
"@vuepress/plugin-nprogress": "^1.2.0",
|
||||||
"@vuepress/plugin-search": "^1.2.0",
|
"@vuepress/plugin-search": "^1.2.0",
|
||||||
"chalk": "^4.0.0",
|
"chalk": "^4.0.0",
|
||||||
"json2yaml": "^1.1.0",
|
"json2yaml": "^1.1.0",
|
||||||
"js-yaml": "^3.13.1",
|
"js-yaml": "^3.13.1",
|
||||||
"docsearch.js": "^2.5.2",
|
"docsearch.js": "^2.5.2",
|
||||||
|
|
@ -40,10 +40,8 @@
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"maintainers": [
|
"maintainers": [{
|
||||||
{
|
"name": "Evan xu",
|
||||||
"name": "Evan xu",
|
"email": "894072666@qq.com"
|
||||||
"email": "894072666@qq.com"
|
}]
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
margin-bottom .2rem
|
margin-bottom .2rem
|
||||||
p
|
p
|
||||||
margin 0
|
margin 0
|
||||||
&.tip, &.warning, &.danger
|
&.tip, &.warning, &.danger, &.note
|
||||||
padding .5rem 1.5rem
|
padding .5rem 1.5rem
|
||||||
border-left-width .5rem
|
border-left-width .5rem
|
||||||
border-left-style solid
|
border-left-style solid
|
||||||
|
|
@ -29,6 +29,10 @@
|
||||||
color darken(red, 40%)
|
color darken(red, 40%)
|
||||||
a
|
a
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
|
&.note
|
||||||
|
background-color #E8F5FA
|
||||||
|
border-color #157BAE
|
||||||
|
color darken(#157BAE, 40%)
|
||||||
&.right
|
&.right
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
font-size 0.9rem
|
font-size 0.9rem
|
||||||
|
|
@ -66,7 +70,7 @@
|
||||||
.theme-mode-dark
|
.theme-mode-dark
|
||||||
.custom-block
|
.custom-block
|
||||||
&.warning
|
&.warning
|
||||||
background-color rgba(255, 247, 208, .2)
|
background-color rgba(255, 247, 208, .2)
|
||||||
color darken(#ffe564, 35%)
|
color darken(#ffe564, 35%)
|
||||||
.custom-block-title
|
.custom-block-title
|
||||||
color darken(#ffe564, 15%)
|
color darken(#ffe564, 15%)
|
||||||
|
|
@ -77,4 +81,7 @@
|
||||||
background-color rgba(255, 230, 230, .4)
|
background-color rgba(255, 230, 230, .4)
|
||||||
color darken(red, 50%)
|
color darken(red, 50%)
|
||||||
a
|
a
|
||||||
color $accentColor
|
color $accentColor
|
||||||
|
&.note
|
||||||
|
background-color rgba(243, 245, 247, .2)
|
||||||
|
color darken(#157BAE, 0%)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ h1, h2, h3, h4, h5, h6
|
||||||
float none
|
float none
|
||||||
padding-right: 0
|
padding-right: 0
|
||||||
margin-left: -.9rem
|
margin-left: -.9rem
|
||||||
|
|
||||||
|
|
||||||
// 普通卡片列表
|
// 普通卡片列表
|
||||||
.cardListContainer
|
.cardListContainer
|
||||||
|
|
@ -31,14 +31,14 @@ h1, h2, h3, h4, h5, h6
|
||||||
background var(--bodyBg)
|
background var(--bodyBg)
|
||||||
border-radius 3px
|
border-radius 3px
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
display flex
|
display flex
|
||||||
box-shadow 1px 1px 2px 0 rgba(0,0,0,.06)
|
box-shadow 1px 1px 2px 0 rgba(0,0,0,.06)
|
||||||
transition all .4s
|
transition all .4s
|
||||||
&:hover
|
&:hover
|
||||||
text-decoration none
|
text-decoration none
|
||||||
box-shadow: 0 10px 20px -10px var(--randomColor, rgba(0,0,0,0.15));
|
box-shadow: 0 10px 20px -10px var(--randomColor, rgba(0,0,0,0.15));
|
||||||
transform: translateY(-5px)
|
transform: translateY(-3px) scale(1.01, 1.01)
|
||||||
img
|
img
|
||||||
// transform rotate(8deg) scale(1.1, 1.1)
|
// transform rotate(8deg) scale(1.1, 1.1)
|
||||||
box-shadow 3px 2px 7px rgba(0, 0, 0, 0.15)
|
box-shadow 3px 2px 7px rgba(0, 0, 0, 0.15)
|
||||||
div p
|
div p
|
||||||
|
|
@ -55,7 +55,7 @@ h1, h2, h3, h4, h5, h6
|
||||||
div
|
div
|
||||||
flex 1
|
flex 1
|
||||||
display inline-block
|
display inline-block
|
||||||
float right
|
float right
|
||||||
padding 1rem 0
|
padding 1rem 0
|
||||||
p
|
p
|
||||||
margin 0
|
margin 0
|
||||||
|
|
@ -96,20 +96,21 @@ h1, h2, h3, h4, h5, h6
|
||||||
width calc(100%/3 - 1rem)
|
width calc(100%/3 - 1rem)
|
||||||
margin .5rem
|
margin .5rem
|
||||||
background var(--mainBg)
|
background var(--mainBg)
|
||||||
border 1px solid rgba(0,0,0,0.08)
|
border 1px solid rgba(0,0,0,0.1)
|
||||||
box-sizing: border-box
|
box-sizing: border-box
|
||||||
border-radius 3px
|
border-radius 3px
|
||||||
overflow hidden
|
overflow hidden
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
box-shadow 2px 2px 10px rgba(0,0,0,.04)
|
box-shadow 2px 2px 10px rgba(0,0,0,.04)
|
||||||
display flex
|
display flex
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
align-content: stretch;
|
align-content: stretch;
|
||||||
transition: box-shadow .3s
|
transition: all .4s
|
||||||
&:hover
|
&:hover
|
||||||
box-shadow 1px 1px 20px rgba(0,0,0,.07)
|
box-shadow 1px 1px 20px rgba(0,0,0,.1)
|
||||||
|
transform: translateY(-3px)
|
||||||
.box-img
|
.box-img
|
||||||
overflow hidden
|
overflow hidden
|
||||||
position relative
|
position relative
|
||||||
|
|
@ -119,15 +120,15 @@ h1, h2, h3, h4, h5, h6
|
||||||
width 100%
|
width 100%
|
||||||
height auto
|
height auto
|
||||||
transition: all .3s
|
transition: all .3s
|
||||||
&:hover
|
// &:hover
|
||||||
img
|
// img
|
||||||
transform: scale(1.1, 1.1)
|
// transform: scale(1.1, 1.1)
|
||||||
opacity .75
|
// opacity .75
|
||||||
a
|
a
|
||||||
color var(--textColor)
|
color var(--textColor)
|
||||||
transition: color .3s
|
transition: color .3s
|
||||||
&:hover
|
&:hover
|
||||||
color $accentColor
|
// color $accentColor
|
||||||
text-decoration none
|
text-decoration none
|
||||||
.box-info
|
.box-info
|
||||||
padding: .8rem 1rem
|
padding: .8rem 1rem
|
||||||
|
|
@ -141,13 +142,13 @@ h1, h2, h3, h4, h5, h6
|
||||||
.box-footer
|
.box-footer
|
||||||
overflow hidden
|
overflow hidden
|
||||||
padding: .8rem 1rem
|
padding: .8rem 1rem
|
||||||
border-top: 1px solid rgba(0,0,0,0.05)
|
border-top: 1px solid rgba(0,0,0,0.1)
|
||||||
img
|
img
|
||||||
width 1.8rem
|
width 1.8rem
|
||||||
height 1.8rem
|
height 1.8rem
|
||||||
border-radius 50%
|
border-radius 50%
|
||||||
float left
|
float left
|
||||||
span
|
span
|
||||||
line-height 1.8rem
|
line-height 1.8rem
|
||||||
float left
|
float left
|
||||||
margin-left: .6rem
|
margin-left: .6rem
|
||||||
|
|
@ -168,9 +169,9 @@ h1, h2, h3, h4, h5, h6
|
||||||
border-color: var(--borderColor)
|
border-color: var(--borderColor)
|
||||||
.box-footer
|
.box-footer
|
||||||
border-color: var(--borderColor)
|
border-color: var(--borderColor)
|
||||||
|
|
||||||
// 卡片列表的响应
|
// 卡片列表的响应
|
||||||
@media (max-width: 900px)
|
@media (max-width: 900px)
|
||||||
.cardListContainer
|
.cardListContainer
|
||||||
.card-list
|
.card-list
|
||||||
.card-item.row-4
|
.card-item.row-4
|
||||||
|
|
@ -180,7 +181,7 @@ h1, h2, h3, h4, h5, h6
|
||||||
.card-item.row-4
|
.card-item.row-4
|
||||||
width calc(100%/3 - 1rem)
|
width calc(100%/3 - 1rem)
|
||||||
|
|
||||||
@media (max-width: 720px)
|
@media (max-width: 720px)
|
||||||
.cardListContainer
|
.cardListContainer
|
||||||
.card-list
|
.card-list
|
||||||
.card-item.row-3, .card-item.row-4
|
.card-item.row-3, .card-item.row-4
|
||||||
|
|
@ -191,8 +192,8 @@ h1, h2, h3, h4, h5, h6
|
||||||
.card-list
|
.card-list
|
||||||
.card-item.row-3, .card-item.row-4
|
.card-item.row-3, .card-item.row-4
|
||||||
width calc(100%/2 - 1rem)
|
width calc(100%/2 - 1rem)
|
||||||
|
|
||||||
@media (max-width: 500px)
|
@media (max-width: 500px)
|
||||||
.cardListContainer
|
.cardListContainer
|
||||||
.card-list
|
.card-list
|
||||||
.card-item.row-1, .card-item.row-2, .card-item.row-3, .card-item.row-4
|
.card-item.row-1, .card-item.row-2, .card-item.row-3, .card-item.row-4
|
||||||
|
|
@ -202,4 +203,4 @@ h1, h2, h3, h4, h5, h6
|
||||||
.cardImgListContainer
|
.cardImgListContainer
|
||||||
.card-list
|
.card-list
|
||||||
.card-item.row-1, .card-item.row-2, .card-item.row-3, .card-item.row-4
|
.card-item.row-1, .card-item.row-2, .card-item.row-3, .card-item.row-4
|
||||||
width calc(100% - 1rem)
|
width calc(100% - 1rem)
|
||||||
|
|
|
||||||
|
|
@ -1,118 +0,0 @@
|
||||||
const re = /.*\/(.*?)\.(html|md)/
|
|
||||||
|
|
||||||
export function getPagesList(posts) {
|
|
||||||
let pagesList = {}
|
|
||||||
let tagGroup = {}
|
|
||||||
|
|
||||||
// 过滤非文章页
|
|
||||||
posts = filterNotArticle(posts)
|
|
||||||
|
|
||||||
// 对页面数据二次处理和排序
|
|
||||||
const pages = posts.map(post => {
|
|
||||||
// const execs = re.exec(post.relativePath)
|
|
||||||
const date = new Date(post.frontmatter.date || post.lastUpdated)
|
|
||||||
const pathArr = post.relativePath.split('/')
|
|
||||||
|
|
||||||
return {
|
|
||||||
// ...post,
|
|
||||||
title: post.title,
|
|
||||||
path: post.path,
|
|
||||||
// lastUpdated: post.lastUpdated,
|
|
||||||
updateTimestamp: date.getTime(), // 更新日期的时间戳
|
|
||||||
// filename: execs ? execs['1'] : '',
|
|
||||||
formatDay: formatDate(date),
|
|
||||||
year: date.getFullYear(),
|
|
||||||
tag: /\./g.test(pathArr[0]) ? pathArr[1].split('.')[1] : pathArr[0] // 区分是单独合集的笔记还是文章
|
|
||||||
}
|
|
||||||
}).sort((a, b) => b.updateTimestamp - a.updateTimestamp)
|
|
||||||
|
|
||||||
|
|
||||||
// 根据年份对数据分组
|
|
||||||
let pageYearArr = []
|
|
||||||
let pageYearObj = {}
|
|
||||||
pages.forEach( page => {
|
|
||||||
// 全部
|
|
||||||
if (!pageYearObj[page.year]){
|
|
||||||
pageYearArr.push({
|
|
||||||
year: page.year,
|
|
||||||
pageList: [page]
|
|
||||||
})
|
|
||||||
pageYearObj[page.year] = page
|
|
||||||
} else {
|
|
||||||
pageYearArr.forEach(ele => {
|
|
||||||
if (ele.year == page.year){
|
|
||||||
ele.pageList.push(page)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加入标签属性
|
|
||||||
if (!tagGroup[page.tag]) {
|
|
||||||
tagGroup[page.tag] = []
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 根据标签分组
|
|
||||||
for (let item in tagGroup) { // 循环标签
|
|
||||||
|
|
||||||
for(let i in pageYearArr) { // 循环全部
|
|
||||||
const filterTag = pageYearArr[i].pageList.filter(page => { // 按标签过滤
|
|
||||||
return page.tag === item
|
|
||||||
})
|
|
||||||
if (filterTag.length) { // 该年份中有数据才加入
|
|
||||||
tagGroup[item].push({
|
|
||||||
year: pageYearArr[i].year,
|
|
||||||
pageList: filterTag
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pagesList.tagGroup = tagGroup
|
|
||||||
pagesList.allPage = pageYearArr // 加入全部
|
|
||||||
|
|
||||||
return pagesList
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function getTopKPosts(posts, len, currentPath) {
|
|
||||||
return filterNotArticle(posts, currentPath)
|
|
||||||
.map(post => {
|
|
||||||
const execs = re.exec(post.relativePath)
|
|
||||||
return {
|
|
||||||
...post,
|
|
||||||
updateTimestamp: (new Date(post.frontmatter.date || post.lastUpdated)).getTime(), // 更新日期的时间戳
|
|
||||||
filename: execs ? execs['1'] : '',
|
|
||||||
formatDay: formatDate(new Date(post.frontmatter.date || post.lastUpdated))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.sort((a, b) => b.updateTimestamp - a.updateTimestamp)
|
|
||||||
.slice(0,len)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 过滤没有frontmatter数据的 和 非文章页面的,
|
|
||||||
function filterNotArticle(posts, currentPath){
|
|
||||||
return posts.filter(post => {
|
|
||||||
const { frontmatter, path } = post;
|
|
||||||
if (currentPath) { // 过滤是当前页面的
|
|
||||||
return frontmatter && frontmatter.permalink && frontmatter.title && frontmatter.article !== false && path !== currentPath;
|
|
||||||
} else {
|
|
||||||
return frontmatter && frontmatter.permalink && frontmatter.title && frontmatter.article !== false;
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 日期格式化
|
|
||||||
function formatDate(date) {
|
|
||||||
if (!(date instanceof Date)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// return `${date.getFullYear()}/${zero(date.getMonth() + 1)}/${zero(date.getDate())}`
|
|
||||||
return `${zero(date.getMonth() + 1)}-${zero(date.getDate())}`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 补0
|
|
||||||
function zero(d) {
|
|
||||||
return d.toString().padStart(2,'0')
|
|
||||||
}
|
|
||||||
|
|
@ -246,22 +246,22 @@ function resolveItem (item, pages, base, groupDepth = 1) {
|
||||||
|
|
||||||
|
|
||||||
// 类型判断
|
// 类型判断
|
||||||
export function type(o){
|
export function type (o) {
|
||||||
const s = Object.prototype.toString.call(o)
|
const s = Object.prototype.toString.call(o)
|
||||||
return s.match(/\[object (.*?)\]/)[1].toLowerCase()
|
return s.match(/\[object (.*?)\]/)[1].toLowerCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 日期格式化(只获取年月日)
|
// 日期格式化(只获取年月日)
|
||||||
export function dateFormat(date) {
|
export function dateFormat (date) {
|
||||||
if (!(date instanceof Date)) {
|
if (!(date instanceof Date)) {
|
||||||
date = new Date(date)
|
date = new Date(date)
|
||||||
}
|
}
|
||||||
return `${date.getUTCFullYear()}-${zero(date.getUTCMonth()+1)}-${zero(date.getUTCDate())}`
|
return `${date.getUTCFullYear()}-${zero(date.getUTCMonth() + 1)}-${zero(date.getUTCDate())}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 小于10补0
|
// 小于10补0
|
||||||
export function zero(d){
|
export function zero (d) {
|
||||||
return d.toString().padStart(2,'0')
|
return d.toString().padStart(2, '0')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取时间的时间戳
|
// 获取时间的时间戳
|
||||||
|
|
@ -280,8 +280,8 @@ export function compareDate (a, b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将特殊符号编码(应用于url)
|
// 将特殊符号编码(应用于url)
|
||||||
export function encodeUrl(str) {
|
export function encodeUrl (str) {
|
||||||
str = str + ''
|
str = str + ''
|
||||||
str = str.replace(/ |((?=[\x21-\x7e]+)[^A-Za-z0-9])/g, '-')
|
str = str.replace(/ |((?=[\x21-\x7e]+)[^A-Za-z0-9])/g, '-')
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { type, compareDate, encodeUrl } from './index'
|
import { type, compareDate } from './index'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 过滤非文章页
|
* 过滤非文章页
|
||||||
|
|
@ -6,7 +6,7 @@ import { type, compareDate, encodeUrl } from './index'
|
||||||
*/
|
*/
|
||||||
export function filterPosts (posts) {
|
export function filterPosts (posts) {
|
||||||
posts = posts.filter(item => {
|
posts = posts.filter(item => {
|
||||||
const { frontmatter: { pageComponent, article, home }} = item
|
const { frontmatter: { pageComponent, article, home } } = item
|
||||||
return !(pageComponent || article === false || home === true) // 存在页面组件、article字段为false,以及首页
|
return !(pageComponent || article === false || home === true) // 存在页面组件、article字段为false,以及首页
|
||||||
})
|
})
|
||||||
return posts
|
return posts
|
||||||
|
|
@ -47,31 +47,29 @@ export function sortPostsByDate (posts) {
|
||||||
* 按分类和标签分组
|
* 按分类和标签分组
|
||||||
* @param {Array} posts 按时间排序之后的文章数据
|
* @param {Array} posts 按时间排序之后的文章数据
|
||||||
*/
|
*/
|
||||||
export function groupPosts(posts) {
|
export function groupPosts (posts) {
|
||||||
const categoriesObj = {}
|
const categoriesObj = {}
|
||||||
const tagsObj = {}
|
const tagsObj = {}
|
||||||
|
|
||||||
for (let i = 0, postsL = posts.length; i < postsL; i++) {
|
for (let i = 0, postsL = posts.length; i < postsL; i++) {
|
||||||
const { frontmatter: { categories, tags }} = posts[i]
|
const { frontmatter: { categories, tags } } = posts[i]
|
||||||
if (type(categories) === 'array') {
|
if (type(categories) === 'array') {
|
||||||
categories.forEach(item => {
|
categories.forEach(item => {
|
||||||
if (item) { // 分类值是有效的
|
if (item) { // 分类值是有效的
|
||||||
const encodeItem = encodeUrl(item)
|
if (!categoriesObj[item]) {
|
||||||
if (!categoriesObj[encodeItem]) {
|
categoriesObj[item] = []
|
||||||
categoriesObj[encodeItem] = []
|
|
||||||
}
|
}
|
||||||
categoriesObj[encodeItem].push(posts[i])
|
categoriesObj[item].push(posts[i])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (type(tags) === 'array') {
|
if (type(tags) === 'array') {
|
||||||
tags.forEach(item => {
|
tags.forEach(item => {
|
||||||
if (item) { // 标签值是有效的
|
if (item) { // 标签值是有效的
|
||||||
const encodeItem = encodeUrl(item)
|
if (!tagsObj[item]) {
|
||||||
if (!tagsObj[encodeItem]) {
|
tagsObj[item] = []
|
||||||
tagsObj[encodeItem] = []
|
|
||||||
}
|
}
|
||||||
tagsObj[encodeItem].push(posts[i])
|
tagsObj[item].push(posts[i])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -86,18 +84,18 @@ export function groupPosts(posts) {
|
||||||
* 获取所有分类和标签
|
* 获取所有分类和标签
|
||||||
* @param {Object} groupPosts 按分类和标签分组之后的文章数据
|
* @param {Object} groupPosts 按分类和标签分组之后的文章数据
|
||||||
*/
|
*/
|
||||||
export function categoriesAndTags(groupPosts) {
|
export function categoriesAndTags (groupPosts) {
|
||||||
const categoriesArr = []
|
const categoriesArr = []
|
||||||
const tagsArr = []
|
const tagsArr = []
|
||||||
|
|
||||||
for(let key in groupPosts.categories) {
|
for (let key in groupPosts.categories) {
|
||||||
categoriesArr.push({
|
categoriesArr.push({
|
||||||
key,
|
key,
|
||||||
length: groupPosts.categories[key].length
|
length: groupPosts.categories[key].length
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
for(let key in groupPosts.tags) {
|
for (let key in groupPosts.tags) {
|
||||||
tagsArr.push({
|
tagsArr.push({
|
||||||
key,
|
key,
|
||||||
length: groupPosts.tags[key].length
|
length: groupPosts.tags[key].length
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue