界面成功渲染

This commit is contained in:
WindowBird 2025-09-29 14:45:33 +08:00
parent 1c2d767ffe
commit d0202bcca6
14 changed files with 334 additions and 17 deletions

45
app/app.config.ts Normal file
View File

@ -0,0 +1,45 @@
export default defineAppConfig({
global: {
picture: {
dark: 'https://cbu01.alicdn.com/img/ibank/O1CN01uZ3fTP1Bs31lE2Mlf_!!0-0-cib.jpg',
light: 'https://cbu01.alicdn.com/img/ibank/O1CN01uZ3fTP1Bs31lE2Mlf_!!0-0-cib.jpg',
alt: 'My profile picture'
},
meetingLink: 'https://chuangtewulian.1688.com/page/index.html',
email: 'ui-pro@nuxt.com',
available: true
},
ui: {
colors: {
primary: 'blue',
neutral: 'neutral'
},
pageHero: {
slots: {
container: 'py-18 sm:py-24 lg:py-32',
title: 'mx-auto max-w-xl text-pretty text-3xl sm:text-4xl lg:text-5xl',
description: 'mt-2 text-md mx-auto max-w-2xl text-pretty sm:text-md text-muted'
}
}
},
footer: {
credits: `Built with Nuxt UI • © ${new Date().getFullYear()}`,
colorMode: false,
links: [{
'icon': 'i-simple-icons-discord',
'to': 'https://www.douyin.com/user/MS4wLjABAAAAdPkGyADnJFLrZBwDM9U7faUJs-wmmyEU9L34SS0CKhs',
'target': '_blank',
'aria-label': 'Nuxt on Discord'
}, {
'icon': 'i-simple-icons-x',
'to': 'https://chuangtewulian.1688.com/page/index.html',
'target': '_blank',
'aria-label': 'Nuxt on X'
}, {
'icon': 'i-simple-icons-github',
'to': 'https://chuangtewulian.1688.com/page/index.html',
'target': '_blank',
'aria-label': 'Nuxt UI on GitHub'
}]
}
})

View File

@ -1,6 +1,40 @@
<script lang="ts" setup>
const colorMode = useColorMode()
const color = computed(() => colorMode.value === 'dark' ? '#020618' : 'white')
useHead({
meta: [
{charset: 'utf-8'},
{name: 'viewport', content: 'width=device-width, initial-scale=1'},
{key: 'theme-color', name: 'theme-color', content: color}
],
link: [
{rel: 'icon', href: '/favicon.ico'}
],
htmlAttrs: {
lang: 'en'
}
})
useSeoMeta({
titleTemplate: '%s - 创特物联',
ogImage: 'https://ui.nuxt.com/assets/templates/nuxt/portfolio-light.png',
twitterImage: 'https://ui.nuxt.com/assets/templates/nuxt/portfolio-light.png',
twitterCard: 'summary_large_image'
})
</script>
<template>
<div>
<NuxtRouteAnnouncer />
<NuxtWelcome />
</div>
<UApp>
<NuxtLayout>
<UMain class="relative">
<NuxtPage/>
</UMain>
</NuxtLayout>
</UApp>
</template>

26
app/assets/css/main.css Normal file
View File

@ -0,0 +1,26 @@
@import "tailwindcss";
@import "@nuxt/ui";
@source "../../../content/**/*";
@theme static {
--font-sans: 'Public Sans', sans-serif;
--font-serif: 'Instrument Serif', serif;
}
:root {
--ui-container: var(--container-4xl);
::selection {
color: #282a30;
background-color: #c8c8c8;
}
}
.dark {
::selection {
color: #ffffff;
background-color: #474747;
}
}

View File

@ -0,0 +1,24 @@
<script setup lang="ts">
const { footer } = useAppConfig()
</script>
<template>
<UFooter
class="z-10 bg-default"
:ui="{ left: 'text-muted text-xs' }"
>
<template #left>
{{ footer.credits }}
</template>
<template #right>
<template v-if="footer?.links">
<UButton
v-for="(link, index) of footer?.links"
:key="index"
v-bind="{ size: 'xs', color: 'neutral', variant: 'ghost', ...link }"
/>
</template>
</template>
</UFooter>
</template>

View File

@ -0,0 +1,26 @@
<script lang="ts" setup>
import type {NavigationMenuItem} from '@nuxt/ui'
defineProps<{
links: NavigationMenuItem[]
}>()
</script>
<template>
<div class="fixed top-2 sm:top-4 mx-auto left-1/2 transform -translate-x-1/2 z-10">
<UNavigationMenu
:items="links"
:ui="{
link: 'px-2 py-1',
linkLeadingIcon: 'hidden'
}"
class="bg-muted/80 backdrop-blur-sm rounded-full px-2 sm:px-4 border border-muted/50 shadow-lg shadow-neutral-950/5"
color="neutral"
variant="link"
>
<template #list-trailing>
<ColorModeButton/>
</template>
</UNavigationMenu>
</div>
</template>

View File

@ -0,0 +1,76 @@
<script setup lang="ts">
const colorMode = useColorMode()
const nextTheme = computed(() => (colorMode.value === 'dark' ? 'light' : 'dark'))
const switchTheme = () => {
colorMode.preference = nextTheme.value
}
const startViewTransition = (event: MouseEvent) => {
if (!document.startViewTransition) {
switchTheme()
return
}
const x = event.clientX
const y = event.clientY
const endRadius = Math.hypot(
Math.max(x, window.innerWidth - x),
Math.max(y, window.innerHeight - y)
)
const transition = document.startViewTransition(() => {
switchTheme()
})
transition.ready.then(() => {
const duration = 600
document.documentElement.animate(
{
clipPath: [
`circle(0px at ${x}px ${y}px)`,
`circle(${endRadius}px at ${x}px ${y}px)`
]
},
{
duration: duration,
easing: 'cubic-bezier(.76,.32,.29,.99)',
pseudoElement: '::view-transition-new(root)'
}
)
})
}
</script>
<template>
<ClientOnly>
<UButton
:aria-label="`Switch to ${nextTheme} mode`"
:icon="`i-lucide-${nextTheme === 'dark' ? 'sun' : 'moon'}`"
color="neutral"
variant="ghost"
size="sm"
class="rounded-full"
@click="startViewTransition"
/>
<template #fallback>
<div class="size-4" />
</template>
</ClientOnly>
</template>
<style>
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
}
::view-transition-new(root) {
z-index: 9999;
}
::view-transition-old(root) {
z-index: 1;
}
</style>

View File

@ -1,12 +1,12 @@
<script setup lang="ts">
<script lang="ts" setup>
</script>
<template>
<div>
<UContainer class="sm:border-x border-default pt-10">
<AppHeader :links="navLinks" />
<slot />
<AppFooter />
<AppHeader :links="navLinks"/>
<slot/>
<AppFooter/>
</UContainer>
</div>
</template>

11
app/pages/index.vue Normal file
View File

@ -0,0 +1,11 @@
<script lang="ts" setup>
</script>
<template>
<text>1</text>
</template>
<style scoped>
</style>

23
app/utils/links.ts Normal file
View File

@ -0,0 +1,23 @@
import type {NavigationMenuItem} from '@nuxt/ui'
export const navLinks: NavigationMenuItem[] = [{
label: '首页',
to: '/'
}, {
label: '主营产品',
}, {
label: '新闻资讯',
}, {
label: '发展史',
}, {
label: '关于我们',
}]

View File

@ -1,12 +1,21 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: '2025-07-15',
devtools: { enabled: true },
modules: ['@nuxt/eslint', '@nuxt/ui', '@nuxt/image'],
fonts: {
providers: {
google: false, // 禁用 Google Fonts
googleicons: false // 禁用 Google Icons
}
}
compatibilityDate: '2025-07-15',
devtools: {enabled: true},
modules: ['@nuxt/eslint', '@nuxt/ui', '@nuxt/image'],
fonts: {
providers: {
google: false, // 禁用 Google Fonts
googleicons: false // 禁用 Google Icons
}
},
css: ['~/assets/css/main.css'],
nitro: {
prerender: {
routes: [
'/',
],
crawlLinks: true
}
},
})

View File

@ -18,5 +18,10 @@
"typescript": "^5.9.2",
"vue": "^3.5.21",
"vue-router": "^4.5.1"
},
"devDependencies": {
"autoprefixer": "^10.4.21",
"postcss": "^8.5.6",
"tailwindcss": "^4.1.13"
}
}

View File

@ -32,6 +32,16 @@ importers:
vue-router:
specifier: ^4.5.1
version: 4.5.1(vue@3.5.22(typescript@5.9.2))
devDependencies:
autoprefixer:
specifier: ^10.4.21
version: 10.4.21(postcss@8.5.6)
postcss:
specifier: ^8.5.6
version: 8.5.6
tailwindcss:
specifier: ^4.1.13
version: 4.1.13
packages:

10
pnpm-workspace.yaml Normal file
View File

@ -0,0 +1,10 @@
ignoredBuiltDependencies:
- '@parcel/watcher'
- '@tailwindcss/oxide'
- esbuild
- unrs-resolver
- vue-demi
onlyBuiltDependencies:
- better-sqlite3
- sharp

18
tailwind.config.js Normal file
View File

@ -0,0 +1,18 @@
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
content: [
'./components/**/*.{js,vue,ts}',
'./layouts/**/*.vue',
'./pages/**/*.vue',
'./plugins/**/*.{js,ts}',
'./app.vue',
'./error.vue'
],
theme: {
extend: {
// 自定义主题配置
}
},
plugins: []
}