完成布局

This commit is contained in:
2025-07-25 11:36:11 +08:00
parent 9dafb6ff47
commit c4995bbe9a
22 changed files with 381 additions and 124 deletions

View File

@@ -50,13 +50,12 @@ provide('navigation', navigation)
<template>
<UApp>
<NuxtLoadingIndicator />
<AppHeader />
<UMain>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</UMain>
<ClientOnly>
<LazyUContentSearch
:files="files"

View File

@@ -48,20 +48,20 @@
<div>
<NuxtLink
to="/"
class="flex items-center px-4 py-3 text-sm font-medium rounded-xl text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800 hover:shadow-sm transition-all duration-200"
class="flex items-center px-4 py-2 text-sm font-medium rounded-lg text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800 hover:shadow-sm transition-all duration-200"
:class="{
'bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 shadow-sm':
$route.path === '/',
}"
>
<Icon name="uim:house-user" class="text-primary mr-2" size="20" />
<Icon name="lucide-home" class="text-primary mr-2" size="20" />
站点首页
</NuxtLink>
</div>
<!-- 分隔线 -->
<div class="flex items-center px-6 p-1 ">
<div class="flex items-center px-8 p-1 ">
<ContentDirectory />
</div>

View File

@@ -3,6 +3,7 @@
<UContentNavigation
:navigation="directoryNavigation"
highlight
color="primary"
variant="pill"
/>

View File

@@ -0,0 +1,42 @@
<script setup lang="ts">
const providers = ref([
{
label: 'Google',
icon: 'i-simple-icons-google',
color: 'neutral',
variant: 'subtle'
},
{
label: 'GitHub',
icon: 'i-simple-icons-github',
color: 'neutral',
variant: 'subtle'
}
])
const fields = ref([
{
name: 'email',
type: 'text',
label: 'Email'
},
{
name: 'password',
type: 'password',
label: 'Password'
}
])
</script>
<template>
<UAuthForm
class="max-w-md"
title="Login"
description="Enter your credentials to access your account."
icon="i-lucide-user"
:fields="fields"
:providers="providers"
:separator="{
icon: 'i-lucide-user'
}"
/>
</template>

View File

@@ -1,42 +1,57 @@
<script setup lang="ts">
import type { NuxtError } from '#app'
import type { NuxtError } from "#app";
definePageMeta({
layout: "default",
});
defineProps<{
error: NuxtError
}>()
error: NuxtError;
}>();
useHead({
htmlAttrs: {
lang: 'en'
}
})
lang: "zh-CN",
},
});
useSeoMeta({
title: 'Page not found',
description: 'We are sorry but this page could not be found.'
})
title: "Page not found",
description: "We are sorry but this page could not be found.",
});
const { data: navigation } = await useAsyncData('navigation', () => queryCollectionNavigation('docs'))
const { data: files } = useLazyAsyncData('search', () => queryCollectionSearchSections('docs'), {
server: false
})
const { data: navigation } = await useAsyncData("navigation", () =>
queryCollectionNavigation("docs"),
);
const { data: files } = useLazyAsyncData(
"search",
() => queryCollectionSearchSections("docs"),
{
server: false,
},
);
provide('navigation', navigation)
provide("navigation", navigation);
</script>
<template>
<UApp>
<AppHeader />
<UError :error="error" />
<UError
:error="error"
:clear="{
size: 'xl',
icon: 'i-lucide-arrow-left',
class: 'rounded-full',
}"
redirect="/"
/>
<AppFooter />
<ClientOnly>
<LazyUContentSearch
:files="files"
:navigation="navigation"
/>
<LazyUContentSearch :files="files" :navigation="navigation" />
</ClientOnly>
</UApp>
</template>

View File

@@ -18,11 +18,52 @@ const pageFontSizeClass = computed(() => {
return `text-${selectedFontSize.value}`
})
const { data: page } = await useAsyncData(route.path, () => queryCollection('docs').path(route.path).first())
// 根据路由参数构建内容路径
const path = computed(() => {
const slug = route.params.slug;
// 处理 slug 参数
if (!slug) {
return '/'; // 如果没有 slug返回根路径
}
const pathValue = Array.isArray(slug) ? slug.join("/") : slug;
// 确保路径以 / 开头,不以 / 结尾
const normalizedPath = `/${pathValue}`.replace(/\/+$/, ""); // 使用 /+ 匹配多个连续的斜杠
return normalizedPath;
});
// URL 解码并验证路径
const queryPath = computed(() => {
try {
return decodeURIComponent(path.value);
} catch (error) {
console.error('URL decode error:', error);
return path.value; // 如果解码失败,返回原始路径
}
});
const { data: page } = await useAsyncData(
`page-${route.path}`, // 使用更具体的 key
() => queryCollection('docs').path(queryPath.value).first(),
{
default: () => null // 提供默认值
}
);
if (!page.value) {
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })
throw createError({
statusCode: 404,
statusMessage: '文档不存在',
message: '当前页面不存在,请您检查路径是否正确',
fatal: true
});
}
const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
return queryCollectionItemSurroundings('docs', route.path, {
fields: ['description']

View File

@@ -1,4 +1,8 @@
<script setup lang="ts">
definePageMeta({
layout: 'default'
})
const { data: page } = await useAsyncData('index', () => queryCollection('landing').path('/').first())
if (!page.value) {
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })

View File

@@ -1,96 +0,0 @@
<template>
<div class="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900 py-12 px-4 sm:px-6 lg:px-8">
<div class="max-w-md w-full space-y-8">
<div>
<h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900 dark:text-white">
登录您的账户
</h2>
<p class="mt-2 text-center text-sm text-gray-600 dark:text-gray-300">
<NuxtLink to="/register" class="font-medium text-blue-600 hover:text-blue-500">
创建新账户
</NuxtLink>
</p>
</div>
<form class="mt-8 space-y-6" @submit.prevent="handleLogin">
<div class="rounded-md shadow-sm -space-y-px">
<div>
<label for="email" class="sr-only">邮箱地址</label>
<input
id="email"
v-model="email"
type="email"
required
class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="邮箱地址"
>
</div>
<div>
<label for="password" class="sr-only">密码</label>
<input
id="password"
v-model="password"
type="password"
required
class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm"
placeholder="密码"
>
</div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center">
<input
id="remember-me"
v-model="rememberMe"
type="checkbox"
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
>
<label for="remember-me" class="ml-2 block text-sm text-gray-900 dark:text-gray-300">
记住我
</label>
</div>
<div class="text-sm">
<a href="#" class="font-medium text-blue-600 hover:text-blue-500">
忘记密码
</a>
</div>
</div>
<div>
<button
type="submit"
class="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
>
<span class="absolute left-0 inset-y-0 flex items-center pl-3">
<svg class="h-5 w-5 text-blue-500 group-hover:text-blue-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clip-rule="evenodd" />
</svg>
</span>
登录
</button>
</div>
</form>
</div>
</div>
</template>
<script setup lang="ts">
const email = ref('')
const password = ref('')
const rememberMe = ref(false)
const handleLogin = () => {
// TODO: Implement actual login logic
console.log('Login attempt:', { email: email.value, password: password.value, rememberMe: rememberMe.value })
// For demo purposes, redirect to home
navigateTo('/')
}
useSeoMeta({
title: '登录 - Easy Docs',
description: '登录您的 Easy Docs 账户'
})
</script>

View File

@@ -1,2 +0,0 @@
title: Getting Started
icon: false

View File

@@ -0,0 +1,2 @@
title: 简单文档
icon: i-lucide-book-open

View File

@@ -1 +1,2 @@
title: Essentials
icon: i-lucide-book-open

View File

@@ -0,0 +1,2 @@
title: Getting Started
icon: i-lucide-book-open

View File

@@ -0,0 +1,86 @@
---
title: Introduction
description: Welcome to Nuxt UI Pro documentation template.
navigation:
icon: i-lucide-house
---
This template is a ready-to-use documentation template made with [Nuxt UI Pro](https://ui.nuxt.com/pro), a collection of premium components built on top of [Nuxt UI](https://ui.nuxt.com) to create beautiful & responsive Nuxt applications in minutes.
There are already many websites based on this template:
::card-group
:::card
---
icon: i-simple-icons-nuxtdotjs
target: _blank
title: Nuxt
to: https://nuxt.com
---
The Nuxt website
:::
:::card
---
icon: i-simple-icons-nuxtdotjs
target: _blank
title: Nuxt UI
to: https://ui.nuxt.com
---
The documentation of `@nuxt/ui` and `@nuxt/ui-pro`
:::
:::card
---
icon: i-simple-icons-nuxtdotjs
target: _blank
title: Nuxt Image
to: https://image.nuxt.com
---
The documentation of `@nuxt/image`
:::
:::card
---
icon: i-simple-icons-nuxtdotjs
target: _blank
title: Nuxt Content
to: https://content.nuxt.com
---
The documentation of `@nuxt/content`
:::
:::card
---
icon: i-simple-icons-nuxtdotjs
target: _blank
title: Nuxt Devtools
to: https://devtools.nuxt.com
---
The documentation of `@nuxt/devtools`
:::
:::card
---
icon: i-simple-icons-nuxtdotjs
target: _blank
title: Nuxt Hub
to: https://hub.nuxt.com
---
The best place to manage your projects, environments and variables.
:::
::
## Key Features
This template includes a range of features designed to streamline documentation management:
- **Powered by** [**Nuxt 3**](https://nuxt.com): Utilizes the latest Nuxt framework for optimal performance.
- **Built with** [**Nuxt UI**](https://ui.nuxt.com) **and** [**Nuxt UI Pro**](https://ui.nuxt.com/pro): Integrates a comprehensive suite of UI components.
- [**MDC Syntax**](https://content.nuxt.com/usage/markdown) **via** [**Nuxt Content**](https://content.nuxt.com): Supports Markdown with component integration for dynamic content.
- [**Nuxt Studio**](https://content.nuxt.com/docs/studio) **Compatible**: Offers integration with Nuxt Studio for content editing.
- **Auto-generated Sidebar Navigation**: Automatically generates navigation from content structure.
- **Full-Text Search**: Includes built-in search functionality for content discovery.
- **Optimized Typography**: Features refined typography for enhanced readability.
- **Dark Mode**: Offers dark mode support for user preference.
- **Extensive Functionality**: Explore the template to fully appreciate its capabilities.

View File

@@ -0,0 +1,29 @@
---
title: Installation
description: Get started with Nuxt UI Pro documentation template.
navigation:
icon: i-lucide-download
---
::tip{target="_blank" to="https://content.nuxt.com/templates/docs"}
Use this template on Nuxt Studio and start your documentation in seconds.
::
## Quick Start
You can start a fresh new project with:
```bash [Terminal]
npx nuxi init -t github:nuxt-ui-pro/docs
```
or create a new repository from GitHub:
1. Open <https://github.com/nuxt-ui-pro/docs>
2. Click on `Use this template` button
3. Enter repository name and click on `Create repository from template` button
4. Clone your new repository
5. Install dependencies with your favorite package manager
6. Start development server
That's it! You can now start writing your documentation in the [`content/`](https://content.nuxt.com/usage/content-directory) directory 🚀

View File

@@ -0,0 +1,127 @@
---
title: Usage
description: Learn how to write and customize your documentation.
navigation:
icon: i-lucide-sliders
---
This is only a basic example of what you can achieve with [Nuxt UI Pro](https://ui.nuxt.com/pro/guide), you can tweak it to match your needs. The template uses several Nuxt modules underneath like [`@nuxt/content`](https://content.nuxt.com) for the content and [`nuxt-og-image`](https://nuxtseo.com/og-image/getting-started/installation) for social previews.
::tip
---
target: _blank
to: https://ui.nuxt.com/getting-started/installation/pro/nuxt
---
Learn more on how to take the most out of Nuxt UI Pro!
::
## Writing content
You can just start writing `.md` or `.yml` files in the [`content/`](https://content.nuxt.com/usage/content-directory) directory to have your pages updated. The navigation will be automatically generated in the left aside and in the mobile menu. You will also be able to go through your content with full-text search.
## App Configuration
In addition to `@nuxt/ui-pro` configuration through the `app.config.ts`, this template lets you customize the `Header`, `Footer` and the `Table of contents` components.
### Header
```ts [app.config.ts]
export default defineAppConfig({
header: {
title: '',
to: '/',
// Logo configuration
logo: {
alt: '',
// Light mode
light: '',
// Dark mode
dark: ''
},
// Show or hide the search bar
search: true,
// Show or hide the color mode button
colorMode: true,
// Customize links
links: [{
'icon': 'i-simple-icons-github',
'to': 'https://github.com/nuxt-ui-pro/docs',
'target': '_blank',
'aria-label': 'GitHub'
}]
},
})
```
### Footer
```ts [app.config.ts]
export default defineAppConfig({
footer: {
// Update bottom left credits
credits: `Copyright © ${new Date().getFullYear()}`,
// Show or hide the color mode button
colorMode: false,
// Customize links
links: [{
'icon': 'i-simple-icons-nuxtdotjs',
'to': 'https://nuxt.com',
'target': '_blank',
'aria-label': 'Nuxt Website'
}, {
'icon': 'i-simple-icons-discord',
'to': 'https://discord.com/invite/ps2h6QT',
'target': '_blank',
'aria-label': 'Nuxt UI on Discord'
}, {
'icon': 'i-simple-icons-x',
'to': 'https://x.com/nuxt_js',
'target': '_blank',
'aria-label': 'Nuxt on X'
}, {
'icon': 'i-simple-icons-github',
'to': 'https://github.com/nuxt/ui',
'target': '_blank',
'aria-label': 'Nuxt UI on GitHub'
}]
},
})
```
### Table of contents
```ts [app.config.ts]
export default defineAppConfig({
toc: {
// Title of the main table of contents
title: 'Table of Contents',
// Customize links
bottom: {
// Title of the bottom table of contents
title: 'Community',
// URL of your repository content folder
edit: 'https://github.com/nuxt-ui-pro/docs/edit/main/content',
links: [{
icon: 'i-lucide-star',
label: 'Star on GitHub',
to: 'https://github.com/nuxt/ui',
target: '_blank'
}, {
icon: 'i-lucide-book-open',
label: 'Nuxt UI Pro docs',
to: 'https://ui.nuxt.com/getting-started/installation/pro/nuxt',
target: '_blank'
}, {
icon: 'i-simple-icons-nuxtdotjs',
label: 'Purchase a license',
to: 'https://ui.nuxt.com/pro/purchase',
target: '_blank'
}]
}
}
})
```
::tip{target="_blank" to="https://content.nuxt.com/docs/studio/config"}
This template integrates with Nuxt Studio, providing a visual interface for editing your documentation - perfect for non-technical contributors.
::

View File

@@ -22,6 +22,12 @@ export default defineNuxtConfig({
toc: {
searchDepth: 1
}
},
pathMeta: {
slugifyOptions: {
// Keep everything except invalid chars, this will preserve Chinese characters
remove: /[$*+~()'"!\-=#?:@.]/g,
}
}
}
},