开发右侧导航栏
更新时间: 2021-02-10 19:03:36
写这个的初衷也是因为别的小朋友都有,我!不!能!没!有!(别的小朋友还在BAT呢。。。。嗯,我也想要 TAT )
# 原理
每个页面的
this.$page
都有headers
,这个headers
取自这个页面的h2
和h3
,如下图: 可以使用这个数据把右侧导航栏渲染出来。默认主题默认情况下,当用户通过滚动查看页面的不同部分时,嵌套的标题链接和
URL
中的Hash
值会实时更新,这个行为可以通过以下的配置来禁用:
// .vuepress/config.js
module.exports = {
themeConfig: {
activeHeaderLinks: false, // 默认值:true
}
}
1
2
3
4
5
6
2
3
4
5
6
也就是说滚动滚动条的时候,页面的URL是会根据所看内容来变化的,我们可以利用这个特性来判断当前哪个链接要高亮。
# 开发侧边栏组件
原理已经清楚了,开干!
# 开发RightNav组件
这个组件用来承载侧边栏的数据,代码如下:
<template>
<div class="right-nav">
<div v-for="item in headers" :class="['right-menu-item', 'level'+item.level, { active: item.slug === hashText }]">
<a :href="'#'+item.slug">{{item.title}}</a>
</div>
</div>
</template>
<script>
export default {
data(){
return {
headers:[],
hashText:''
}
},
mounted() {
this.getHeadersData()
this.getHashText()
},
watch: {
//$route发生改变的时候重新获取headers,以及判断当前的hashText
$route () {
this.getHeadersData()
this.getHashText()
}
},
methods:{
getHeadersData(){
this.headers = this.$page.headers || []
},
getHashText () {
this.hashText = decodeURIComponent(window.location.hash.slice(1))
}
}
}
</script>
1
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
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
这个组件主要就是每当$route发生改变的时候重新获取headers的数据,以及hashText
# 在Page组件中使用
在Page组件中使用RightNav,并且判断是否显示RightNav
//...
<RightNav v-if="hasRightNav"></RightNav>
//...
<script>
//...
hasRightNav(){
const { $frontmatter, $themeConfig, $page } = this
const { sidebar } = $frontmatter
return (
$page.headers &&
($frontmatter && sidebar && sidebar !== false) !== false
)
}
//...
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
判断是否显示RightNav
有以下条件:
this.$page.headers
不为空this.$frontmatter
中没有将sidebar
置为false
# 根据屏幕宽度修改是否可见
这一步几乎就是css
的操作啦,略去讲解啦,大家都会对不对。
- 当屏幕宽度大于1250时,显示
RightNav
,隐藏默认主题自带的.sidebar-sub-headers
- 当屏幕宽度小于1250时,隐藏
RightNav
, 显示默认主题自带的.sidebar-sub-headers