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. 创建组件结构

bash 复制代码
├── src
│   └── sections
│   	├── Nav.vue
│       ├── Home.vue
│       ├── Projects.vue
│       └── About.vue (未完成)
│   └── router
│   	├── index.js
│   └── constants
│   	├── index.js
│   └── assets
│   	├── logo.png 
│   	├── ...其他静态文件

你可以在仓库的对应文件夹下面找到所需要的静态文件:50days50projects

💻 3. 代码

html 复制代码
<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">
                    <div
                        v-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

html 复制代码
<template>
    <section class="flex min-h-screen w-full flex-col" id="Home">
        <div
            class="absolute inset-0 z-0 bg-[url(@/assets/showcase-bg.png)] bg-center bg-no-repeat opacity-20" />
        <div
            class="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

html 复制代码
<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">
            <div
                v-for="item in projectList"
                :key="item.id"
                class="relative overflow-hidden rounded-lg">
                <div>
                    <img :src="item.image" :alt="item.title" />
                </div>

                <div
                    class="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

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

html 复制代码
<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

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

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」


🧠 页面是外壳,逻辑是灵魂。步步为营,才能无懈可击。

相关推荐
阿金要当大魔王~~几秒前
uniapp 页面标签 传值 ————— uniapp 定义 接口
前端·javascript·uni-app·1024程序员节
全栈软件开发24 分钟前
uniapp三端影视源码苹果cms自动采集电影视频网站源码前端源码带VIP
前端·uni-app·影视源码
chxii42 分钟前
10.4FormData :前端文件上传与表单数据处理的核心工具
前端
AntBlack1 小时前
不当韭菜 : 好像真有点效果 ,想藏起来自己用了
前端·后端·python
楊无好1 小时前
react中props的使用
前端·react.js·前端框架
一个处女座的程序猿O(∩_∩)O1 小时前
Vue-Loader 深度解析:原理、使用与最佳实践
前端·javascript·vue.js
一点一木2 小时前
火山方舟 Responses API 实战指南:从概念到「公司尽调 Dossier 生成器」
前端·人工智能·api
还是大剑师兰特2 小时前
TypeScript 面试题及详细答案 100题 (91-100)-- 工程实践与框架集成
前端·javascript·typescript·1024程序员节
可触的未来,发芽的智生2 小时前
触摸未来2025-10-25:蓝图绘制
javascript·python·神经网络·程序人生·自然语言处理
用户47949283569152 小时前
typeof null === 'object':JavaScript 最古老的 bug 为何 30 年无法修复?
前端·javascript·面试