从零用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/
随机推荐
- O2OA(翱途)开发平台如何在流程表单中使用基于Vue的ElementUI组件?
本文主要介绍如何在O2OA中进行审批流程表单或者工作流表单设计,O2OA主要采用拖拽可视化开发的方式完成流程表单的设计和配置,不需要过多的代码编写,业务人员可以直接进行修改操作. 在流程表单设计界面, ...
- 自动化SQL注入工具——Sqlmap
Sqlmap – 简介 Sqlmap是一个自动化检测和利用SQL注入漏洞的免费开源工具 1.支持对多种数据库进行注入测试,能够自动识别数据库类型并注入 2.支持多种注入技术,并且能够自动探测使用合适的 ...
- AntdPro中formItemProps和fieldProps的区别
最近在工作中接触到了 antd 和 antd pro,作为一个 react 和 antd 新人,在学习和使用中遇到了不少的问题,下边就常见的一个问题来进行记录,后续还会记录更多的问题以及心得 Form ...
- Linux设置字符编码
一.Linux设置字符编码 1.什么是字符编码 字符编码可以实现对非英文字符的支持,防止非英文字符的乱码. 2.国内常用的字符编码 UTF-8 GBK 3.设置字符编码 我们可以对Linux系统的字符 ...
- Java服务刚启动时,一小波接口超时排查全过程
原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明. 简介 我们组有一个流量较大的Java服务,每次发代码时,服务都会有一小波接口超时,之前简单分析过,发现这些超时的 ...
- Android Studio开发小项目
"莆仙小馆"--莆田文化展示APP 文化展示程序目的在于应用科学技术助推家乡优秀传统文化的展示与交流.通过图片.视频.音频等展示方式向用户立体地展示一个文化城邦.传统文化与科学技术 ...
- 青少年CTF平台-Web-Robots
题目信息 题目名称:Robots 题目描述:昨天十三年社团讲课,讲了Robots.txt的作用,小刚上课没有认真听课正在着急,你能不能帮帮忙? 题目难度:一颗星 解题过程 访问题目链接 在这里插入图片 ...
- 洛谷 P1122 最大子树和 题解
一道入门的树形DP. 首先我们对于数据进行有序化处理,这便于我们利用数据结构特点(可排序性)来发觉数据性质(有序.单调.子问题等等性质),以便于后续的转化.推理和处理.有序化可以"转化和创造 ...
- [grpc]双向tls加密认证
前言 假设gRPC服务端的主机名为qw.er.com,需要为gRPC服务端和客户端之间的通信配置tls双向认证加密. 生成证书 生成ca根证书.生成过程会要求填写密码.CN.ON.OU等信息,记住密码 ...
- 8、Spring之基于注解的自动装配
8.1.场景模拟 8.1.1.UserDao接口及实现类 package org.rain.spring.dao; /** * @author liaojy * @date 2023/8/5 - 18 ...