本站主题
# 本站主题
本站使用的主题继承自 Vdoing
主题,主题官方文档 (opens new window) 和 主题源码 (opens new window)。
其他优秀主题:vuepress-theme-reco 1.x (opens new window),vuepress-theme-reco 2.x (opens new window)
# 快速体验
# clone the project
git clone https://github.com/xugaoyi/vuepress-theme-vdoing.git
# enter the project directory
cd vuepress-theme-vdoing
# install dependency 注意:如安装不成功请关闭淘宝源。
yarn install # or npm install
# develop
yarn dev # or npm run dev
2
3
4
5
6
7
8
9
10
11
这样你就能在本地跑起来 vdoing主题 作者的博客,官方也是建议直接clone整个项目,在此基础上替换你自己的内容即可。
官方提示
- 不建议在原默认vuepress项目上单独安装使用本主题包,而是clone我的整个项目再替换你自己的内容即可。
- 修改config.js配置后需要重新启动项目才会生效。
- 更多关于项目上手的问题,请查阅 问答 (opens new window)。
如果你打算这么做,那么你需要先看看 问答 (opens new window) 中所需掌握的知识,然后在此基础上替换你自己的内容即搭建自己的博客了。
但我不建议这么做,建议在你上面初始化的vuepress项目中安装vdoing主题,然后继承该主题,再去修改。
这样做的好处:
- 可以对vdoing主题深度修改
- 也可以享受到后续vdoing主题的升级服务
# 安装Vdoing主题
在上面初始化的vuepress项目中安装最新的vdoing主题
yarn add vuepress-theme-vdoing -D
npm install vuepress-theme-vdoing -D
// Make sure to add code blocks to your code group
# 继承vdoing主题
VuePress 主题的继承 (opens new window),可以先看看官方教程,大概了解一下。
# 使用
创建一个继承自 vdoing 主题的派生主题,只需要在主题配置中配置 extend 选项:
docs
目录下新建.vuepress/theme
目录- 在该目录下新建
index.js
// docs/.vuepress/theme/index.js
module.exports = {
extend: 'vuepress-theme-vdoing' // 这里根路径指向 node_modules
}
2
3
4
# 继承策略
父主题的所有能力都会"传递"给子主题,对于文件级别的约定,子主题可以通过在同样的位置创建同名文件来覆盖它;
对于某些主题配置选项,如 globalLayout,子主题也可以通过同名配置来覆盖它。
文件级别的约定如下:
- 全局组件,即放置在
theme/global-components
中的 Vue 组件。 - 组件,即放置在
theme/components
中的 Vue 组件。 - 全局的样式和调色板,即放置在
theme/styles
中的index.styl
和palette.styl
。 - HTML 模板,即放置在
theme/templates
中的dev.html
和ssr.html
。 - 主题水平的客户端增强文件,即
theme/enhanceApp.js
。
# 组件覆盖
组件的覆盖,是基于父主题中对应组件的代码来修改。
即将父主题中对应的组件直接复制到 docs/.vuepress/theme/components
中修改。
如此一来,就可以实现轻松地 “篡改” 一个父主题的某个部分。
docs/.vuepress/theme
目录下新建components
目录- 需要修改Vdoing主题中的哪个组件,就到
node_modules/vuepress-theme-vdoing/components
目录下复制对应的组件到上面新建的目录下修改 - 新增的功能模块直接新建对应的组件即可
覆盖或新增的组件可以直接查看我的github源码 (opens new window),以下简单说明修改的部分
# Home.vue(复制)
<template #mainRight>
<BloggerBar v-if="$themeConfig.blogger" />
<CategoriesBar
v-if="homeData.category !== false &&
$themeConfig.category !== false &&
$categoriesAndTags.categories.length"
:categoriesData="$categoriesAndTags.categories"
:length="10"
/>
<TagsBar
v-if="homeData.tag !== false &&
$themeConfig.tag !== false &&
$categoriesAndTags.tags.length"
:tagsData="$categoriesAndTags.tags"
:length="30"
/>
<div
class="custom-html-box card-box"
v-if="homeSidebarB"
v-html="homeSidebarB"
></div>
</template>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mainRight 插槽中新增对 homeData.category 和 homeData.tag 的判断,这也是首页新增的配置项,具体说明查看前面介绍篇
# NavLinks.vue(复制)
repoLink() {
const { repo, repoLink } = this.$site.themeConfig
// repoLink 默认为true
if (repo && repoLink !== false) {
return /^https?:/.test(repo) ? repo : `https://github.com/${repo}`
}
return null
}
2
3
4
5
6
7
8
repoLink函数中新增对 repoLink
配置项的判断,这也是新增的主题配置项,具体说明查看前面介绍篇
# NavLinksBefore.vue(新建)
<template>
<nav class="nav-links" v-if="beforeLinks.length">
<!-- before links -->
<div class="nav-item" v-for="item in beforeLinks" :key="item.link">
<DropdownLink v-if="item.type === 'links'" :item="item" />
<NavLink v-else :item="item" />
</div>
</nav>
</template>
<script>
import DropdownLink from '@theme/components/DropdownLink.vue'
import NavLink from '@theme/components/NavLink.vue'
export default {
components: { NavLink, DropdownLink },
methods: {
resolveNavLinkItem(linkItem) {
return Object.assign(linkItem, {
type: linkItem.items && linkItem.items.length ? 'links' : 'link',
})
},
},
computed: {
navBefore() {
return this.$themeLocaleConfig.navBefore || this.$site.themeConfig.navBefore || []
},
beforeLinks() {
return (this.navBefore || []).map((link) => {
return Object.assign(this.resolveNavLinkItem(link), {
items: (link.items || []).map(this.resolveNavLinkItem),
})
})
},
},
}
</script>
<style lang="stylus">
.nav-links
display inline-block
margin-right 0.5rem
a
line-height 1.4rem
color inherit
&:hover, &.router-link-active
color $accentColor
.nav-item
position relative
display inline-block
margin-left 1.5rem
line-height 2rem
&:first-child
margin-left 0
// 959
@media (max-width $MQNarrow)
.nav-links
.nav-item
margin-left 1.2rem
@media (max-width $MQMobile)
.nav-links
.nav-item
margin-left 0
@media (min-width $MQMobile)
.nav-links a
&:hover, &.router-link-active
color var(--textColor)
.nav-item > a:not(.external)
&:hover, &.router-link-active
margin-bottom -2px
border-bottom 2px solid lighten($accentColor, 8%)
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
搜索框前面的导航模块,如本站顶部导航的 🔑索引
# Navbar.vue(复制)
<template>
...
<NavLinksBefore class="can-hide" />
<AlgoliaSearchBox v-if="isAlgoliaSearch" :options="algolia" />
<SearchBox v-else-if="$site.themeConfig.search !== false && $page.frontmatter.search !== false" />
<NavLinks class="can-hide" />
...
</template>
<script>
// 导入组件
import NavLinksBefore from './NavLinksBefore.vue'
// 注册组件
components: { SidebarButton, NavLinks, NavLinksBefore, SearchBox, AlgoliaSearchBox },
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
增加 NavLinksBefore
组件模块,其中 class="can-hide"
是用于移动端时可以隐藏
# Sidebar.vue(复制)
<template>
...
<!-- 移动端Nav -->
<NavLinks />
<NavLinksBefore />
...
</template>
<script>
// 导入组件
import NavLinksBefore from './NavLinksBefore.vue'
// 注册组件
components: { SidebarLinks, NavLinks, NavLinksBefore },
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
由于移动端顶部的 NavLinksBefore
会被隐藏,需要在侧边栏中显示出来
# 样式覆盖
样式的覆盖,是基于全局的样式和调色板,即放置在 theme/styles
中的 index.styl
和 palette.styl
。
docs/.vuepress
目录下新建styles
目录- 在该目录下分别新建
index.styl
和palette.styl
文件
最新修改可以直接查看我的github源码 (opens new window)
# index.styl(新建)
/* docs/.vuepress/styles/index.styl */
// 权重要够
#app .theme-container .home-wrapper .banner {
// 重置 .banner 中的 margin-top: 3.6rem; 为 padding-top: 3.6rem;
// 解决主页高度够用也出现滚动条 (由于.theme-container 中 min-height: 100vh; 再magrin的话就会始终超出一个屏幕的高度而出现滚动条)
margin-top: 0;
padding-top: 3.6rem;
// 使主页banner字体颜色跟随主题设置
color: var(--textColor);
}
.home-wrapper .banner .banner-conent .hero p {
// 主页banner heroText下的tagline字体加粗
font-weight: 600;
}
.home-wrapper .banner .banner-conent .feature p,
.home-wrapper .banner .banner-conent .feature h2 {
// 主页 feature 字体加粗
font-weight: bold!important;
}
// 解决目录页宽度够用也换行,使其展示正常
.catalogue-wrapper .catalogue-content dl.inline a:not(.header-anchor) {
width: 100%!important;
}
// footer 让页脚固定在页面底部
.theme-container {
position: relative;
}
.theme-container .home-wrapper,
.theme-container .page,
.theme-container .custom-page {
// footer 大概的高度
padding-bottom: calc(9.65rem + 12px + 2rem);
}
.footer {
position: absolute;
bottom: 0;
width: 100%!important;
}
// 侧边栏目录按钮颜色
.theme-container .sidebar-button {
color: black;
background-color: white;
opacity: 0.6;
}
/* 自定义滚动条样式 */
//定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸
// ::-webkit-scrollbar
// {
// width: 8px;
// height: 8px;
// border-radius: 10px;
// background-color: #F5F5F5;
// }
// /*定义滚动条轨道 内阴影+圆角*/
// ::-webkit-scrollbar-track
// {
// border-radius: 10px;
// -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
// background-color: #F5F5F5;
// }
// /*定义滑块 内阴影+圆角*/
// ::-webkit-scrollbar-thumb
// {
// border-radius: 10px;
// -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
// border-radius: 10px;
// /* 线性渐变 */
// background-image: -webkit-gradient(linear,
// left bottom, left top,
// color-stop(0.44, rgb(60,186,146)),
// color-stop(0.72, rgb(253,187,45)),
// color-stop(0.86, rgb(253,187,45)));
// transition: 0.3s ease-in-out;
// }
// /*定义滑块悬浮样式*/
// ::-webkit-scrollbar-thumb:hover{
// background-image: -webkit-gradient(linear,
// left bottom, left top,
// color-stop(0.44, rgb(253,187,45)),
// olor-stop(0.72, rgb(253,187,45)),
// color-stop(0.86, rgb(60,186,146)));
// transition: 0.3s ease-in-out;
// }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# palette.styl(新建)
//***vdoing主题-样式变量(你可以修改这些变量值以覆盖主题使用的样式变量)***//
// 以下注释的变量仅供参考,主题使用的最新变量请查看:https://github.com/xugaoyi/vuepress-theme-vdoing/blob/master/theme-vdoing/styles/palette.styl
// // 颜色
// $bannerTextColor = #fff // 首页banner区(博客标题)文本颜色
// $bannerTextColor = #004050
// $accentColor = #11A8CD // 主题色
// $activeColor = #ff5722
// $arrowBgColor = #ccc
// $badgeTipColor = #42b983
// $badgeWarningColor = darken(#ffe564, 35%)
// $badgeErrorColor = #DA5961
// // 布局
// $navbarHeight = 3.6rem
// $sidebarWidth = 18rem
// $contentWidth = 860px
// $homePageWidth = 1100px
// $rightMenuWidth = 230px // 右侧菜单
// // 代码块
// $lineNumbersWrapperWidth = 2.5rem
// // 浅色模式
// .theme-mode-light
// --bodyBg: #f4f4f4
// --mainBg: rgba(255,255,255,1)
// --sidebarBg: rgba(255,255,255,.8)
// --blurBg: rgba(255,255,255,.9)
// --textColor: #004050
// --textLightenColor: #0085AD
// --borderColor: rgba(0,0,0,.15)
// // 代码块浅色主题
// --codeBg: #f6f6f6
// --codeColor: #525252
// codeThemeLight()
// // // 代码块深色主题
// // --codeBg: #252526
// // --codeColor: #fff
// // codeThemeDark()
// // 深色模式
// .theme-mode-dark
// --bodyBg: rgb(39,39,43)
// --mainBg: rgba(30,30,34,1)
// --sidebarBg: rgba(30,30,34,.8)
// --blurBg: rgba(30,30,34,.8)
// --textColor: rgb(140,140,150)
// --textLightenColor: #0085AD
// --borderColor: #2C2C3A
// --codeBg: #252526
// --codeColor: #fff
// codeThemeDark()
// // 阅读模式
// .theme-mode-read
// --bodyBg: rgb(240,240,208)
// --mainBg: rgba(245,245,213,1)
// --sidebarBg: rgba(245,245,213,.8)
// --blurBg: rgba(245,245,213,.9)
// --textColor: #004050
// --textLightenColor: #0085AD
// --borderColor: rgba(0,0,0,.15)
// --codeBg: #282c34
// --codeColor: #fff
// codeThemeDark()
// 浅色模式
.theme-mode-light
// 代码块主题颜色
--codeBg: #2a2e36
--codeColor: #D4D4D4
codeThemeDark()
// 代码块的行数字颜色
div[class*="language-"]
&.line-numbers-mode
.line-numbers-wrapper
color #9e9e9e
// 代码块的行高亮颜色
div[class*="language-"]
.highlight-lines
.highlighted
background-color: rgba(0,0,0,0.3);
&.line-numbers-mode
.highlight-lines .highlighted
&:before
background-color: rgba(0,0,0,0.3);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89