菜单

菜单允许您以简单的声明方式描述站点导航结构。菜单分两步:

  1. 定义一个 menu.md 文件,文件内包含其所在目录的菜单结构。
  2. 使用 useContent() 函数获取菜单结构以(在某个模板)进行渲染。 Read more here

文件结构

首先假如文件目录如下:

src/
└── routes/
    └── some/
        ├── menu.md
        ├── layout.tsx
        └── path/
            └── index.tsx  # https://example.com/some/path

导航到 https://example.com/some/path 会激活:

  • src/routes/some/path/index.tsx: 该组件将用于渲染页面内容。
  • src/routes/some/layout.tsx: 此布局将用于为src/routes/some/path/index.tsx提供内容。 在内部布局可以使用src/routes/some/menu.md来渲染菜单。
  • src/routes/some/menu.md: 该文件将用于声明 将由 src/routes/some/layout.tsx 渲染的 菜单结构。

声明菜单结构

使用 menu.md 声明菜单结构

  • 使用标题(#, ##等)来定义菜单深度
  • 使用项目符号列表 (-) 定义菜单项
<!-- File: src/routes/some/menu.md -->

# Docs

## Getting Started

- [Introduction](introduction/index.md)

## Components

- [Basics](/docs/components/basics/index.mdx)

获取菜单结构

在运行时,任何组件都可以使用 useContent() hook获取菜单。返回的类型是 ContentMenu

这个例子将返回:

{
  text: "Docs",
  items: [
    {
      text: "Getting Started",
      items: [
        {
          text: "Introduction",
          href: "/docs/introduction"
        }
      ],
    },
    {
      text: "Components",
      items: [
        {
          text: "Basics",
          href: "/docs/components/basics"
        }
      ],
    },
  ],
}

在layout文件 使用 ContentMenu

尽管可以从属于当前路由的任何组件调用useContent()。 但它通常用于布局组件(或布局使用的组件)中以渲染菜单。此处显示了一个示例用法:

export default component$(() => {
  const { menu } = useContent();
  const { pathname } = useLocation();

  return (
    <div class="menu">
      {menu
        ? menu.items?.map((item) => (
            <>
              <h5>{item.text}</h5>
              <ul>
                {item.items?.map((item) => (
                  <li>
                    <a
                      href={item.href}
                      class={{
                        'is-active': pathname === item.href,
                      }}
                    >
                      {item.text}
                    </a>
                  </li>
                ))}
              </ul>
            </>
          ))
        : null}
    </div>
  );
});
Made with ❤️ by