从零用VitePress搭建博客教程(5) - 如何自定义页面模板、给页面添加独有的className和使页面标题变成侧边目录?
接上一节:从零用VitePress搭建博客教程(4) – 如何自定义首页布局和主题样式修改?
上一节其实我们也简单说了自定义页面模板,这一节更加详细一点说明,开始之前我们要知道在vitePress中,.md的文件是可以直接编写vue的代码的。
比如我们现在来自定义一个前端网址导航页面
八、自定义一些页面模板
1、编写组件代码
想自定义页面模板样式,该如何做呢?
我们先在theme/components下新建siteList.vue文件,编写模板,代码如下:
<template>
<!-- 网址分类模块 -->
<section class="site-section">
<!-- 标题 -->
<h2 class="title">{{ props.title }}</h2>
<!-- 网址列表 -->
<ul class="list">
<li class="item" v-for="(v, index) in props.data" :key="v.name">
<a class="link" :href="v.link" target="_blank">
<span class="num">{{ index + 1 }}</span>
<h4 class="name">{{ v.name }}</h4>
<p class="desc">{{ v.desc }}</p>
</a>
</li>
</ul>
</section>
</template>
<script setup>
const props = defineProps({
title: String,
data: {
type: Array,
default: [],
},
}); </script>
<style lang="scss" scoped>
/*单行文本省略号*/
@mixin single-ellipsis {
overflow: hidden;
word-wrap: normal;
white-space: nowrap;
text-overflow: ellipsis;
}
.site-section {
.title {
color: #222;
}
.list {
display: flex;
flex-wrap: wrap;
list-style: none;
padding-left: 0;
.item {
width: 212px;
margin: 15px 15px 0 0px;
background: #fff;
position: relative;
.link {
width: 210px;
display: block;
border: 1px solid #e3e3e3;
padding-bottom: 8px;
border-radius: 6px;
.num {
display: block;
width: 24px;
height: 18px;
line-height: 18px;
position: absolute;
color: #666;
font-size: 14px;
text-align: center;
right: 5px;
top: 5px;
}
.name {
width: 80%;
height: 26px;
padding-left: 10px;
font-size: 16px;
font-weight: 600;
color: #06a4fa;
margin-top: 15px;
@include single-ellipsis;
}
.desc {
font-size: 12px;
margin: 10px 10px 0;
color: #b1b1b1;
height: 36px;
line-height: 18px;
@include single-ellipsis;
}
&:hover {
text-decoration: none;
border: 1px solid var(--vp-c-brand);
filter: brightness(1.15);
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
transform: rotateY(-0.1deg) scale(1.001) translateZ(0);
transition: all 0.24s ease;
.name {
color: var(--vp-c-brand);
}
.num {
background: var(--vp-c-brand);
color: #fff;
}
}
}
}
}
}
</style>
2、注册组件
上面我们写好组件代码后,需注册为全局组件,如下theme/index.js的配置,把SiteList注册为全局组件,然后在页面引用即可。
// https://vitepress.dev/guide/custom-theme
import { h } from "vue";
import siteList from "./components/siteList.vue"; import DefaultTheme from "vitepress/theme";
import "./styles/custom.scss";
import "./styles/site.scss";
import "./styles/rainbow.css"; export default {
...DefaultTheme,
NotFound: () => "404", // <- this is a Vue 3 functional component
enhanceApp({ app, router, siteData }) {
// app is the Vue 3 app instance from createApp()
// router is VitePress' custom router (see `lib/app/router.js`)
// siteData is a ref of current site-level metadata.
app.component("SiteList", siteList);
},
};
3、如何给页面添加自定义类className
官方就有最简单的配置方法,向特定页面添加额外的类名pageClass:比如给page.md页面配置,只需如下即可
---
pageClass: site-layout
---
然后在下面写样式即可
.site-layout {
...
}
当然还有一种方法是:我们还可以在theme/index.js,通过js添加(Layout配置),这个一个页面可以添加多个className了。
// https://vitepress.dev/guide/custom-theme
import { useData } from "vitepress";
import siteList from "./components/siteList.vue"; import DefaultTheme from "vitepress/theme";
import "./styles/custom.scss";
import "./styles/site.scss";
import "./styles/rainbow.css"; export default {
...DefaultTheme,
NotFound: () => "404", // <- this is a Vue 3 functional component
enhanceApp({ app, router, siteData }) {
// app is the Vue 3 app instance from createApp()
// router is VitePress' custom router (see `lib/app/router.js`)
// siteData is a ref of current site-level metadata.
// 注册全局组件
app.component("SiteList", siteList);
},
// 自定义布局配置
Layout: () => {
const props = {};
// 获取 frontmatter
const { frontmatter } = useData(); /* 添加自定义 class */
if (frontmatter.value?.layoutClass) {
props.class = frontmatter.value.layoutClass;
}
},
};
然后同样的page.md页面,我们可以通过layoutClass设置另一个className了,如下
---
layoutClass: site-page
pageClass: site-layout
---
4、页面使用组件
同样还是上面的page.md,我们使用组件如下
---
pageClass: site-layout
--- <SiteList v-for="model in siteData" :key="model.title" :title="model.title" :data="model.items" />
<script setup>
// 网址导航页面的数据
import siteData from "./data/page.js";
</script>
效果

5、如何使页面标题变成侧边目录呢?
从上面图中可以看出,我们发现右边没有侧边导航,那么如何使页面标题变成侧边目录呢?
这个时候需要用到@mdit-vue/shared,siteList.vue组件修改代码如下
<template>
<!-- 网址分类模块 -->
<!-- <backTop></backTop> -->
<section class="site-section">
<!-- 瞄点标题 -->
<h2 class="title" :id="createTitle">
{{ props.title }}
<a class="anchor" :href="`#${createTitle}`" aria-hidden="true"></a>
</h2>
<!-- 网址列表 -->
<ul class="list">
<li class="item" v-for="(v, index) in props.data" :key="v.name">
<a class="link" :href="v.link" target="_blank">
<span class="num">{{ index + 1 }}</span>
<h4 class="name">{{ v.name }}</h4>
<p class="desc">{{ v.desc }}</p>
</a>
</li>
</ul>
</section>
</template>
<script setup>
import { computed } from "vue";
import { slugify } from "@mdit-vue/shared";
const props = defineProps({
title: String,
data: {
type: Array,
default: [],
},
}); // 生成侧边栏markdown的目录
const createTitle = computed(() => {
return slugify(props.title);
});
</script>
发现目录已经有了,效果如下:

这个时候目录是在页面右边的,那么如何变成在左侧边栏呢?我们通过样式调整即可,site.scss
/**
网址导航页面样式
**/ .site-layout {
/*布局调整*/
.VPDoc {
.container {
max-width: 100% !important;
justify-content: flex-start !important;
.aside {
order: 1;
}
.content {
order: 2;
max-width: 100% !important;
.content-container {
max-width: 100% !important;
}
}
.main {
height: auto;
overflow: hidden;
.vp-doc h2 {
margin: 0;
}
}
}
}
/* 隐藏底部的在 github 上编辑此页模块*/
.VPDocFooter {
display: none;
}
}

6、如何自定义页面的底部?
我们新建一个siteFooter.vue组件,然后在theme/index.js通过h函数配置即可,这里使用到doc-after插槽,
默认主题布局中可用插槽的完整列表:https://process1024.github.io/vitepress/guide/theme-introduction
<template>
<div class="site-footer">
网址导航自定义底部信息
</div>
</template>
mport { h } from "vue";
import siteFooter from "./components/siteFooter.vue";
import DefaultTheme from "vitepress/theme";
export default {
...DefaultTheme,
NotFound: () => "404", // <- this is a Vue 3 functional component
enhanceApp({ app, router, siteData }) {
// app is the Vue 3 app instance from createApp()
// router is VitePress' custom router (see `lib/app/router.js`)
// siteData is a ref of current site-level metadata.
// 注册全局组件
},
// 自定义布局配置
Layout: () => {
return h(DefaultTheme.Layout, props, {
// 自定义文档底部,使用doc-after插槽
"doc-after": () => h(siteFooter),
});
},
};

从零用VitePress搭建博客教程(5) - 如何自定义页面模板、给页面添加独有的className和使页面标题变成侧边目录?的更多相关文章
- 手把手教从零开始在GitHub上使用Hexo搭建博客教程(四)-使用Travis自动部署Hexo(2)
前言 前面一篇文章介绍了Travis自动部署Hexo的常规使用教程,也是个人比较推荐的方法. 前文最后也提到了在Windows系统中可能会有一些小问题,为了在Windows系统中也可以实现使用Trav ...
- 手把手教从零开始在GitHub上使用Hexo搭建博客教程(三)-使用Travis自动部署Hexo(1)
前言 前面两篇文章介绍了在github上使用hexo搭建博客的基本环境和hexo相关参数设置等. 基于目前,博客基本上是可以完美运行了. 但是,有一点是不太好,就是源码同步问题,如果在不同的电脑上写文 ...
- 手把手教从零开始在GitHub上使用Hexo搭建博客教程(二)-Hexo参数设置
前言 前文手把手教从零开始在GitHub上使用Hexo搭建博客教程(一)-附GitHub注册及配置介绍了github注册.git相关设置以及hexo基本操作. 本文主要介绍一下hexo的常用参数设置. ...
- 手把手教从零开始在GitHub上使用Hexo搭建博客教程(一)-附GitHub注册及配置
前言 有朋友问了我关于博客系统搭建相关的问题,由于是做开发相关的工作,我给他推荐的是使用github的gh-pages服务搭建个人博客. 推荐理由: 免费:github提供gh-pages服务是免费的 ...
- Hexo搭建博客教程(1) - 安装环境与本地搭建
前言 搭建个人博客一般有两种选择,一个是使用WordPress,但是需要将博客搭建在服务器上,不过搭建好后写文章方便,适合没有程序基础的人使用.另一个是使用Hexo,相对简洁高效,不需要服务器,既可以 ...
- Hexo+NexT(零):最全Hexo+Next搭建博客教程
快速.简洁且高效的博客框架 有位大神说,喜欢写博客的人的人,折腾博客会经历三个阶段.找到一个免费空间,搭建一个博客,很欣喜,很有成就感,此为一阶段:受限免费空间各种限制,自己买空间和域名,实现对博客的 ...
- Hexo搭建博客教程(2) - 博客的简单个性化配置
本章主要讲博客的个性化,譬如站点的基本配置(语言.头像.站点图标等).安装新的Hexo主题(NexT主题)以及主题的配置. 1. 修改站点配置 打开站点配置文件 ,找到: # Site title: ...
- Hexo搭建博客教程(3) - 远程部署到GitHub Pages
本章讲的是如何将本地的个人项目远程部署到 GitHub Pages,涉及到GitHub的项目仓库.Git的使用,以及Hexo的远程部署等. 1. 安装 hexo-deployer-git 插件 想要将 ...
- 用 Sphinx 搭建博客时,如何自定义插件?
之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建. 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清 ...
- 转载一遍比较好的,django2.1搭建博客教程
非常感谢这位博主,找了几个星期终于找到了 https://www.dusaiphoto.com/article/article-detail/4/
随机推荐
- Taurus .Net Core 微服务开源框架:Admin 插件【4-3】 - 配置管理-Mvc【Plugin-MicroService 微服务】
前言: 继上篇:Taurus .Net Core 微服务开源框架:Admin 插件[4-2] - 配置管理-Mvc[含请求日志打印] 本篇继续介绍下一个内容: 1.系统配置节点:Mvc - Plugi ...
- PostgreSQL 12 文档: SQL 语法
SQL 命令 这部分包含PostgreSQL支持的SQL命令的参考信息.每条命令的标准符合和兼容的信息可以在相关的参考页中找到. 目录 ABORT - 中止当前事务 ALTER AGGREGATE ...
- java.lang.IndexOutOfBoundsException
原因:一个ArrayList数组中没有元素,而你想获取第一个元素,运行是就会报此类型的错误 解决方案:用 array[] 的 .length 查看 数组的长度
- 从0开发WebGPU渲染引擎:开篇
大家好,本系列会从0开始,开发一个基于WebGPU的路径追踪渲染器,使用深度学习降噪.DLSS等AI技术实现实时渲染:并且基于自研的低代码开发平台,让用户可以通过可视化拖拽的方式快速搭建自定义的Web ...
- AcWing 4486. 数字操作题解
题目描述 给定一个整数 \(n\),你可以对该数进行任意次(可以是 \(0\) 次)变换操作. 每次操作为以下两种之一: 将整数 \(n\) 乘以任意一个正整数 \(x\). 将整数 \(n\) 替换 ...
- 给SqlSugar一个优化建议
声明:本作者无恶意只是觉得这个功能很不错,平常工作当中经常用到,自己框架也做了相应的支持,本着技术共享目的. 一.对象组合设置列更新支持 建议度:高 业务场景 1.更新列表需统一设置 例如:修改人ID ...
- Linux 问题:网络相关
防火墙 同网段双网卡 双网关 看服务日志
- 【技术积累】Linux中的命令行【理论篇】【四】
ar命令 命令介绍 ar命令是Linux系统中的一个工具,用于创建.修改和提取静态库文件(archive files).静态库文件是一组已编译的目标文件的集合,可以被链接到可执行文件中. 命令说明 a ...
- 连续下雨天,.net开发者如何预防流感
最近连续下了3天雨,天气变化大,很容易引发感冒咳嗽等疾病.对于.NET技术开发人员来说,如何保持身体健康,保证工作效率是一个很重要的问题. 首先,我们需要注意保持室内空气流通,避免长时间处于封闭的空间 ...
- 如何在达梦数据库中追踪慢SQL
在达梦数据库中,我们可以通过开启日志记录和设置最小执行时间来追踪慢SQL.下面是具体的步骤: 1. 修改dm.ini文件 使用以下命令编辑dm.ini文件: cd /home/dmdba/dmdbms ...