iT邦幫忙

2025 iThome 鐵人賽

DAY 26
0
Vue.js

邊學邊做:Vue.js 實戰養成計畫系列 第 26

Day 26:星際架構啟動 — 專案規劃與版面設計

  • 分享至 

  • xImage
  •  

最後的五天我們要執行Final Mission — 5 日實作計畫,設計一個Galactic Explorer!
把前面 25 天學的所有技能都串起來了~!

而今日目標:建立整體網站結構與風格基底。
A.網站主題名稱與頁面結構

  • 頁面包含:
    • /:主頁(星際入口、導航)
    • /planets:星球知識頁
    • /diary:宇宙觀察日誌
    • /scanner:生物探測器小遊戲
  • 導覽列使用 <router-link> 導頁。

B.設計風格

  • 使用 Element Plus(或 Vuetify)快速統一 UI。
  • 加入星空背景(CSS 或 SVG)。
  • 全站配色建議:深藍(#0b1020)、銀白(#e0e7ff)、螢光紫(#a78bfa)。

0) 前置(確認專案狀態)

在有 package.json 的專案根目錄執行:

*需要 Vue Router、Element Plus*
npm i vue-router@4 element-plus

*(可選)安裝圖示*
npm i @iconify/vue

1) 建路由與頁面結構

a. 建立目錄

src/
 ├─ router/
 │   └─ index.js
 ├─ views/
 │   ├─ Home.vue
 │   ├─ Planets.vue
 │   ├─ Diary.vue
 │   ├─ Scanner.vue
 │   └─ NotFound.vue
 ├─ components/
 │   └─ NavBar.vue
 └─ styles/
     └─ theme.css

b. src/router/index.js

import { createRouter, createWebHistory } from 'vue-router'

import Home from '../views/Home.vue'
import Planets from '../views/Planets.vue'
import Diary from '../views/Diary.vue'
import Scanner from '../views/Scanner.vue'
import NotFound from '../views/NotFound.vue'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', name: 'home', component: Home },
    { path: '/planets', name: 'planets', component: Planets },
    { path: '/diary', name: 'diary', component: Diary },
    { path: '/scanner', name: 'scanner', component: Scanner },
    { path: '/:pathMatch(.*)*', name: '404', component: NotFound }
  ],
  scrollBehavior: () => ({ top: 0 })
})

export default router

2) 啟用 Element Plus、掛上 Router

a. src/main.js

import { createApp } from 'vue'
import App from './App.vue'

// Router
import router from './router'

// Element Plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

// 全站樣式(星空主題)
import './styles/theme.css'

createApp(App)
  .use(router)
  .use(ElementPlus)
  .mount('#app')

b. index.html(加入字體)
<head> 增加(讓標題更有宇宙感):

<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;600;800&display=swap" rel="stylesheet">

3) 版面骨架與導覽列

a. src/components/NavBar.vue

<template>
  <header class="nav">
    <div class="brand">🚀 Galactic Explorer</div>
    <el-menu mode="horizontal" :ellipsis="false" class="menu" router>
      <el-menu-item index="/">首頁</el-menu-item>
      <el-menu-item index="/planets">星球知識</el-menu-item>
      <el-menu-item index="/diary">觀察日誌</el-menu-item>
      <el-menu-item index="/scanner">生物探測器</el-menu-item>
    </el-menu>
  </header>
</template>

<script setup>
/* Element Plus 的 <el-menu router> 會自動根據路由高亮 */
</script>

<style scoped>
.nav {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 16px; backdrop-filter: blur(8px);
  background: linear-gradient(180deg, rgba(11,16,32,.85), rgba(11,16,32,.55));
  border-bottom: 1px solid rgba(167,139,250,.2);
}
.brand {
  font-family: 'Orbitron', system-ui, sans-serif; 
  font-weight: 800; letter-spacing: .5px;
  color: #e0e7ff;
}
.menu { background: transparent; border-bottom: none; }
:deep(.el-menu--horizontal>.el-menu-item.is-active) { 
  color: #a78bfa; border-bottom-color: #a78bfa;
}
</style>

b. src/App.vue

<template>
  <div class="sky">
    <div class="stars"></div>
    <NavBar />
    <main class="page">
      <router-view />
    </main>
    <footer class="ft">© Orbit Coders · Galactic Explorer</footer>
  </div>
</template>

<script setup>
import NavBar from './components/NavBar.vue'
</script>

<style scoped>
.page { max-width: 1080px; margin: 24px auto; padding: 0 16px; }
.ft { text-align:center; color:#94a3b8; padding: 24px 0 40px; }
</style>

4) 星空主題(全站配色+背景)

src/styles/theme.css

:root{
  --bg-deep:#0b1020;       /* 深藍底 */
  --text-main:#e0e7ff;     /* 銀白字 */
  --text-dim:#94a3b8;
  --accent:#a78bfa;        /* 螢光紫 */
  --card:#0f172a;
  color-scheme: dark;
}

html,body,#app{ height:100%; }
body{ margin:0; background: var(--bg-deep); color: var(--text-main); font: 16px/1.6 ui-sans-serif, system-ui; }

.sky { position: relative; min-height:100vh; }
.stars{
  position: fixed; inset: 0; pointer-events: none;
  background:
    radial-gradient(2px 2px at 20% 30%, #fff6 40%, transparent 41%) repeat,
    radial-gradient(1px 1px at 70% 60%, #fff4 40%, transparent 41%) repeat;
  background-size: 600px 600px, 800px 800px;
  animation: drift 120s linear infinite;
  opacity: .6;
}
@keyframes drift {
  from { transform: translate3d(0,0,0); }
  to   { transform: translate3d(-2000px, 800px, 0); }
}

/* 常用卡片 */
.card {
  background: var(--card);
  border: 1px solid rgba(167,139,250,.2);
  border-radius: 16px;
  padding: 16px;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

5) 四個頁面先放上可見內容

1.src/views/Home.vue

<template>
  <section class="hero card">
    <h1>🪐 Galactic Explorer</h1>
    <p>探索星球知識、撰寫觀察日誌,啟動生物探測器小遊戲。</p>
    <el-space wrap>
      <el-button type="primary" @click="$router.push('/planets')">開始探索星球</el-button>
      <el-button @click="$router.push('/diary')">打開觀察日誌</el-button>
      <el-button type="success" @click="$router.push('/scanner')">啟動探測器</el-button>
    </el-space>
  </section>
</template>

<script setup></script>

<style scoped>
.hero h1{ font-family: 'Orbitron', system-ui; font-size: 32px; margin: 0 0 8px; }
.hero p{ color: var(--text-dim); margin: 0 0 12px; }
</style>

2.src/views/Planets.vue

<template>
  <section class="card">
    <h2>🗺️ 星球知識庫</h2>
    <p class="dim">明天會接上 v-for 清單與動態路由到詳細頁。</p>
    <el-alert title="提示" type="info" :closable="false" show-icon>
      範例資料將放在 <code>src/data/planets.json</code>
    </el-alert>
  </section>
</template>

<script setup></script>
<style scoped>.dim{ color:var(--text-dim); }</style>

3.src/views/Diary.vue

<template>
  <section class="card">
    <h2>📓 宇宙觀察日誌</h2>
    <p class="dim">後天會串 localStorage,讓日誌重整後依然保存。</p>
    <el-input
      v-model="draft"
      type="textarea"
      :rows="5"
      placeholder="今天看見了……"
      class="mb"
    />
    <el-button type="primary" @click="save">暫存(僅示意)</el-button>
  </section>
</template>

<script setup>
import { ref } from 'vue'
const draft = ref('')
function save(){ /* Day 28 會補完整 */ }
</script>

<style scoped>
.mb{ margin: 12px 0 0; }
.dim{ color:var(--text-dim); }
</style>

4.src/views/Scanner.vue

<template>
  <section class="card">
    <h2>🛰️ 生物探測器</h2>
    <p class="dim">後續將加入燃料值、隨機生物、動畫與收藏機制。</p>
    <el-button type="success">探索(預留)</el-button>
  </section>
</template>
<script setup></script>
<style scoped>.dim{ color:var(--text-dim); }</style>

5.src/views/NotFound.vue

<template>
  <section class="card">
    <h2>404:迷失在宇宙中</h2>
    <el-button type="primary" @click="$router.push('/')">回到地球</el-button>
  </section>
</template>
<script setup></script>

https://ithelp.ithome.com.tw/upload/images/20251008/20178644lnyiXRI8nz.png
最後執行看看網站會長上面的樣子!你也可以隨自己喜歡去更改設計美編~我們明天會加上展示宇宙星球資訊,能點選切換細節頁面。

參考資源
https://vuejs.org/guide
https://www.runoob.com/vue3


上一篇
Day 25:UI 元件宇宙 — 探索 Vuetify / Element Plus
系列文
邊學邊做:Vue.js 實戰養成計畫26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言