50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | 页面布局 与 Vue Router 路由配置
🖤 Build Daily. Build Differently.
今天我们将基于的 Vue3 + TailwindCSS 项目,进一步拆分页面结构,引入 Vue Router,构建基础导航与页面路由体系。
仓库地址:https://github.com/SunACong/50-vue-projects
🧩 1. 页面结构设计
我们的页面将包含以下几个主要模块:
- 🔗
Nav
:导航栏组件,链接各个页面 - 🏠
Home
:首页介绍 - 📦
Projects
:展示 50 个项目列表 - ℹ️
About
:关于本站与项目介绍
📁 2. 创建组件结构
├── src
│ └── sections
│ ├── Nav.vue
│ ├── Home.vue
│ ├── Projects.vue
│ └── About.vue (未完成)
│ └── router
│ ├── index.js
│ └── constants
│ ├── index.js
│ └── assets
│ ├── logo.png
│ ├── ...其他静态文件
你可以在仓库的对应文件夹下面找到所需要的静态文件:50days50projects
💻 3. 代码
Nav.vue
<template><header class="fixed top-0 right-0 left-0 z-50 bg-black/90"><div class="mx-auto max-w-7xl"><div class="c-space flex items-center justify-end py-5"><div class="mr-auto flex items-center justify-center gap-2"><img class="h-20 w-20" src="@/assets/logo.png" alt="" /></div><div class="flex items-center justify-center gap-10"><divv-for="item in navList":key="item.id"@click="currentTab = item.id":class="['font-mono text-gray-200 transition-all hover:scale-105',currentTab === item.id ? 'border-b-2 border-blue-400' : 'border-b-0',]"><a :href="item.link" @click="goHome">{{ item.title }}</a></div></div></div></div></header>
</template><script setup>import { ref } from 'vue'import { navList } from '../constants/index'const currentTab = ref(1)
</script>
Home.vue
<template><section class="flex min-h-screen w-full flex-col" id="Home"><divclass="absolute inset-0 z-0 bg-[url(@/assets/showcase-bg.png)] bg-center bg-no-repeat opacity-20" /><divclass="c-space z-1 mx-auto mt-30 flex w-full flex-col gap-y-20 text-center font-mono font-medium text-gray-200 sm:mt-60"><p class="text-2xl sm:text-3xl">50 天 50 个项目<span class="waving-hand">👋</span></p><p class="head-text">50 个独特的迷你项目来提升你的 HTML、CSS 和 JavaScript 技能</p><button class="btn border-2 font-mono">🚀让我们开始吧!🚀</button></div></section>
</template><script setup></script><style scoped>.waving-hand {animation-name: wave-animation;animation-duration: 2.5s;animation-iteration-count: infinite;transform-origin: 70% 70%;display: inline-block;}@keyframes wave-animation {0% {transform: rotate(0deg);}10% {transform: rotate(14deg);}20% {transform: rotate(-8deg);}30% {transform: rotate(14deg);}40% {transform: rotate(-4deg);}50% {transform: rotate(10deg);}60% {transform: rotate(0deg);}100% {transform: rotate(0deg);}}
</style>
Projects.vue
<template><section class="c-space" id="Projects"><div class="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5"><divv-for="item in projectList":key="item.id"class="relative overflow-hidden rounded-lg"><div><img :src="item.image" :alt="item.title" /></div><divclass="absolute inset-0 flex flex-col items-center justify-center bg-black/70 font-mono opacity-0 transition-opacity duration-300 ease-in-out hover:opacity-100"><h3 class="mb-4 text-xl font-bold text-white">{{ item.title }}</h3><RouterLink:to="item.link"class="rounded-md bg-blue-500 px-4 py-2 text-white transition-colors duration-200 hover:bg-blue-600">Live Demo</RouterLink></div></div></div></section>
</template><script setup>import { projectList } from '../constants'
</script><style scoped></style>
src/router/index.js
import { createWebHistory, createRouter } from 'vue-router'import ExpandingCards from '@/projects/ExpandingCards.vue'const routes = [{path: '/',name: 'Home',component: () => import('@/sections/Home.vue')},{path: '/Projects',name: 'Projects',component: () => import('@/sections/Projects.vue')}
]const router = createRouter({history: createWebHistory(),routes,
})export default router
App.vue
<template><section class="max-w-8xl mx-auto"><router-view v-if="$route.path !== '/'"></router-view><template v-else><Navbar /><Home /><Projects /></template></section>
</template><script setup>import Navbar from './sections/Navbar.vue'import Home from './sections/Home.vue'import Projects from './sections/Projects.vue'
</script>
main.js
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'createApp(App).use(router).mount('#app')
src/constants/index.js
export const navList = [{ id: 1, title: 'Home', link: '#Home' },{ id: 2, title: 'Peoject', link: '#Projects' },{ id: 3, title: 'About', link: '#About' },
]export const projectList = []
✅ 4. 当前完成状态
- Nav组件完成(包含导航链接)
- Home组件完成(展示欢迎语与介绍)
- Projects组件完成(展示项目概览)
- About组件待完成
- Router配置完成并接入 App.vue
🚀 小结
本日我们构建了基础页面架构与 Vue Router 路由系统,为后续页面跳转与模块拆分打下基础。
📅 下篇预告:开发 Day01 的组件内容「Expanding Cards」
🧠 页面是外壳,逻辑是灵魂。步步为营,才能无懈可击。