---
title: 自定义首页
author: pengzhanbo
icon: material-symbols:home-outline
createTime: 2024/03/02 10:44:03
permalink: /guide/custom-home/
---

## 概述

主题提供了十分灵活的方式来自定义首页。你可以根据你的需求来定制你的首页。

主题通过 `frontmatter` 来定义你的首页。在 `sourceDir` 的 `README.md` 文件中，编写 `frontmatter`。

::: code-tabs
@tab README.md

```md
---
home: true
config:
  - type: custom
---
```

:::

主题 遵循 流式布局的方式来渲染首页，将 首页 在 垂直方向上划分为一个个独立的区域，每个区域应用不同的组件。

通过 `config` 属性，以 数组 的形式，可以定义多个区域。通过 `type` 字段，可以定义该区域的类型。
主题内置了 `banner`， `hero`，`text-image`，`image-text`，`features`，`profile`，`custom` 等不同的类型，
你可以随意组合使用它们，组装成你的自定义首页。
如果它们均不满足你的需求，你也可以 编写自定义组件，来自定义你的首页。

## 配置

### home

- 类型： `boolean`

声明该页面是否为首页

### config

- 类型： `PlumeHomeConfig[]`
- 默认值： `[]`

根据数组的顺序定义页面的区域内容。

```ts
interface PlumeHomeConfigBase {
  /**
   * 该区域的类型，根据类型应用不同的组件
   */
  type: 'banner' | 'hero' | 'text-image' | 'image-text' | 'features' | 'profile' | 'custom' | string
  /**
   * 该区域是否占满全屏
   */
  full?: boolean
  /**
   * 该区域的背景图片
   * 你可以定义在 浅色/暗色 模式下的背景图片
   */
  backgroundImage?: string | { light: string, dark: string }
  /**
   * 该区域的背景 定位方式
   */
  backgroundAttachment?: 'fixed' | 'local'
}
```

## 区域类型

### banner

- 类型： `PlumeThemeHomeBanner`

大屏 banner， 适用于放置在 首页的 首位。

```ts
interface PlumeThemeHomeBanner extends PlumeHomeConfigBase {
  type: 'banner'
  /**
   * 背景大图
   */
  banner?: string
  /**
   * 取值范围： 0 - 1。配置首页 banner 大图的遮罩蒙版不透明度。
   * 支持配置 浅色/深色 模式下 的不同值。当值为 0 时，不显示遮罩蒙版。
   * 这在首页首屏大图比较亮时，可以适当使图片看起来暗一些。
   */
  bannerMask?: number | { light?: number, dark?: number }

  hero?: {
    name: string
    tagline?: string
    text?: string
    actions?: {
      theme?: 'brand' | 'alt'
      text: string
      link?: string
    }
  }
}
```

**示例：**

```md
---
home: true
config:
  -
    type: banner
    banner: https://file.mo7.cc/api/public/bz
    bannerMask:
      light: 0.1
      dark: 0.3
    hero:
      name: 鹏展博
      tagline: Front End Developer
      text: 即使慢，驰而不息，纵会落后，纵会失败，但必须能够到达他所向的目标。
      actions:
        -
          text: 我的博客
          link: /blog/
          theme: brand
        -
          text: Github
          link: https://github.com/pengzhanbo
          theme: alt
---
```

**效果：**

:::demo-wrapper img no-padding
<img src="/images/custom-banner.png" alt="" />
:::

### hero

- 类型： `PlumeThemeHomeHero`

适用于 文档 类型站点，放置于 首位。

```ts
interface PlumeThemeHomeHero extends PlumeHomeConfigBase {
  type: 'hero'
  hero: {
    name: string
    tagline?: string
    text?: string
    actions?: {
      theme?: 'brand' | 'alt'
      text: string
      link?: string
    }
  }
  /**
   * 背景图片，"filter-blur" 为预设效果
   */
  background?: 'filter-blur' | string
  /**
   * 如果是非预设背景，可以设置背景图片的滤镜效果
   */
  filter?: string
}
```

**示例：**

```md
---
home: true
config:
 -
    type: hero
    full: true
    background: filter-blur
    hero:
      name: Theme Plume
      tagline: Vuepress Next Theme
      text: 一个简约的，功能丰富的 vuepress 文档&博客 主题
      actions:
        -
          theme: brand
          text: 快速开始 →
          link: /
        -
          theme: alt
          text: Github
          link: https://github.com/pengzhanbo/vuepress-theme-plume
---
```

**效果：**

:::demo-wrapper img no-padding
<img src="/images/custom-hero.png" alt="Theme Plume" />
:::

### features

- 类型： `PlumeThemeHomeFeatures`

适用于展示 特性、功能、等。

```ts
interface PlumeThemeHomeFeatures extends PlumeHomeConfigBase {
  type: 'features'
  title?: string
  description?: string
  features: PlumeThemeHomeFeature[]
}

interface PlumeThemeHomeFeature {
  icon?: FeatureIcon
  title: string
  details?: string
  link?: string
  linkText?: string
  rel?: string
  target?: string
}

type FeatureIcon = string | {
  src: string
  alt?: string
  width?: string
  height?: string
  wrap?: boolean
} | {
  light: string
  dark: string
  alt?: string
  width?: string
  height?: string
  wrap?: boolean
}
```

**示例：**

```md
---
home: true
config:
  -
    type: features
    features:
      -
        title: 响应式布局
        icon: 💻
        details: 适配移动设备，PC，平板
      -
        title: 博客 & 文档
        icon: 📖
        details: 无论是想写博客，或想写产品文档，或者两者兼顾
      -
        title: 开箱即用
        icon: 🚀
        details: 支持零配置即可使用，也支持丰富的自定义配置
      -
        title: 多语言
        icon: ⚖
        details: 内置了 中文/英文支持，还可以自定义添加更多的语言支持
      -
        title: 双色主题
        icon: 👨‍💻
        details: 支持 浅色/深色 主题，包括代码高亮
      -
        title: 插件
        icon: 📦
        details: 内置丰富的插件，一站式解决网站一般需求
      -
        title: 搜索、评论
        icon: 🔍
        details: 支持多种评论系统，支持本地搜索、Algolia搜索
      -
        title: 加密
        icon: 🔒
        details: 支持全站加密、部分加密（加密目录、加密文章）
      -
        title: Markdown 增强
        icon: 📝
        details: 支持 Markdown 语法，支持 代码块分组、提示容器、任务列表、数学公式、代码演示等
---
```

**效果：**

:::demo-wrapper img no-padding
<img src="/images/custom-features.png" alt="" />
:::

### text-image | image-text

- 类型： `PlumeThemeHomeTextImage`

左右布局的 文本 和 图片。

```ts
interface PlumeThemeHomeTextImage extends PlumeHomeConfigBase {
  type: 'text-image' | 'image-text'
  image: PlumeThemeImage
  width?: number | string
  title?: string
  description?: string
  list: (string | { title?: string, description?: string })[]
}

type PlumeThemeImage =
  | string
  | { src: string, alt?: string }
  | { dark: string, light: string, alt?: string }
```

**示例：**

```md
---
home: true
config:
  -
    type: image-text
    title: 功能
    description: 内置丰富的功能，满足网站一般需求。
    image: /images/plume-1.svg
    list:
      -
        title: 文章信息
        description: 为文章添加标签、分类、字数统计、阅读时间、写作日期等信息。
      -
        title: 评论
        description: 支持 4 种评论系统，你可以自由选择符合你的需求的评论系统。
      -
        title: 搜索
        description: 支持基于 minisearch 的本地搜索， 支持Algolia搜索。
      -
        title: 加密
        description: 支持全站加密、部分加密（加密目录、加密文章）。
      -
        title: 代码复制
        description: 一键复制代码块中的内容
  -
    type: text-image
    title: 博客
    description: 主题默认支持博客，生成你的个人博客。
    image: /images/plume-2.svg
    list:
      -
        title: 文章列表
        description: 通过文章写作日期，自动排序并生成博客文章列表页。
      -
        title: 博主信息
        description: 自定义名称、座右铭、头像，社交媒体链接。
      -
        title: 标签、归档
        description: 自动生成标签页，为文章根据年份进行归档。
---
```

**效果：**

:::demo-wrapper img no-padding
<img src="/images/custom-image-text.png" alt="image-text" />
:::

:::demo-wrapper img no-padding
<img src="/images/custom-text-image.png" alt="text-image" />
:::

### profile

- 类型： `PlumeThemeHomeProfile`

展示个人信息。

```ts
interface PlumeThemeHomeProfile extends PlumeHomeConfigBase {
  type: 'profile'
  name?: string
  description?: string
  avatar?: PlumeThemeImage
  circle?: boolean
}

type PlumeThemeImage =
  | string
  | { src: string, alt?: string }
  | { dark: string, light: string, alt?: string }
```

**示例：**

```md
---
home: true
config:
  -
    type: profile
    name: pengzhanbo
    description: 即使慢，驰而不息，纵会落后，纵会失败，但必须能够到达他所向的目标。
    avatar: /images/avatar.png
---
```

**效果：**

:::demo-wrapper img no-padding
<img src="/images/custom-profile.png" alt="profile" />
:::

### custom

- 类型： `PlumeThemeHomeCustom`

自定义内容，在 `README.md` 的 文件中，编写的 markdown 内容，将会被插入到 对应的区域。

```ts
interface PlumeThemeHomeCustom extends PlumeHomeConfigBase {
  type: 'custom'
}
```

**示例：**

````md
---
home: true
config:
  -
    type: custom
---

### 安装

:::code-tabs
@tab pnpm
```sh
pnpm add vuepress@next vuepress-theme-plume vue
```
@tab npm
```sh
npm install vuepress@next vuepress-theme-plume
```
@tab yarn
```sh
yarn add vuepress@next vuepress-theme-plume
```
:::
````

**效果：**

:::demo-wrapper img no-padding
<img src="/images/custom-content.png" alt="content" />
:::

## 自定义区域类型

当主题内置的区域类型不足以满足你的需求时，你可以自定义区域类型。

每一个自定义区域类型，本质上都是一个组件。

一个 简单的实例如下：

::: code-tabs
@tab your-component.vue

```vue
<script setup lang="ts">
import { HomeBox, type PlumeHomeConfigBase } from 'vuepress-theme-plume/client'

const props = defineProps<PlumeHomeConfigBase & {
  // 组件 props, frontmatter 中的属性将会传递给组件
}>()
</script>

<template>
  <HomeBox
    :type="type"
    :background-image="backgroundImage"
    :background-attachment="backgroundAttachment"
    :full="full"
  >
    <!-- 自定义你的内容 -->
    <div>...</div>
  </HomeBox>
</template>
```

:::

在 `.vuepress/client.ts` 在 `enhance` 钩子中添加 组件
::: code-tabs
@tab .vuepress/client.ts

```ts
import { defineClientConfig } from 'vuepress/client'
import YourComponent from 'your-component.vue'

export default defineClientConfig({
  enhance({ app }) {
    app.component('your-component', YourComponent)
  },
})
```

:::

然后，你就可以在 `README.md` 中使用 `your-component` 了。

```md
---
home: true
config:
  -
    type: 'your-component'
    # ...
---
```
