feat: Phase 3 - API layer + Pinia stores + app integration
- HTTP client (axios interceptors, token mgmt, typed APIs) - Pinia stores: token, user (login/logout), app (dark mode, sidebar) - globalConfig TS types + Window augmentation - Vue Router (hash history, auth guard) - Login/Home/Mine pages (Vant UI) - Vant integration + globalConfig dev script - Build passes (vue-tsc + vite)
This commit is contained in:
125
src/views/home/index.vue
Normal file
125
src/views/home/index.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 首页 (placeholder)
|
||||
*
|
||||
* 使用 Vant Tabbar 实现底部导航切换,
|
||||
* 当前仅展示占位内容,后续集成地图、管网等功能模块。
|
||||
*/
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
/** 当前激活的 Tab */
|
||||
const active = ref(0)
|
||||
|
||||
/**
|
||||
* Tab 切换处理
|
||||
*/
|
||||
function onTabChange(index: number): void {
|
||||
active.value = index
|
||||
if (index === 0) {
|
||||
router.replace('/home')
|
||||
} else if (index === 1) {
|
||||
router.replace('/mine')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="home-page">
|
||||
<!-- 顶部导航栏 -->
|
||||
<van-nav-bar title="舆图智慧水务" fixed placeholder />
|
||||
|
||||
<!-- 页面主体区域 -->
|
||||
<div class="home-content">
|
||||
<div class="welcome-card">
|
||||
<h2>欢迎使用智慧水务</h2>
|
||||
<p>移动端管理平台</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-grid">
|
||||
<div class="feature-item" v-for="i in 4" :key="i">
|
||||
<div class="feature-icon"></div>
|
||||
<span class="feature-label">功能模块 {{ i }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部导航栏 -->
|
||||
<van-tabbar v-model="active" :fixed="true" :placeholder="true" @change="onTabChange">
|
||||
<van-tabbar-item icon="home-o" name="首页">首页</van-tabbar-item>
|
||||
<van-tabbar-item icon="user-o" name="我的">我的</van-tabbar-item>
|
||||
</van-tabbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.home-page {
|
||||
min-height: 100vh;
|
||||
background: var(--color-bg-page);
|
||||
|
||||
:deep(.van-nav-bar) {
|
||||
background: var(--color-primary);
|
||||
--van-nav-bar-title-text-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.home-content {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.welcome-card {
|
||||
background: var(--color-bg-card);
|
||||
border-radius: 12px;
|
||||
padding: 32px 24px;
|
||||
text-align: center;
|
||||
box-shadow: var(--shadow-sm);
|
||||
margin-bottom: 16px;
|
||||
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
color: var(--color-text-primary);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 14px;
|
||||
color: var(--color-text-secondary);
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.feature-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.feature-item {
|
||||
background: var(--color-bg-card);
|
||||
border-radius: 12px;
|
||||
padding: 24px 16px;
|
||||
text-align: center;
|
||||
box-shadow: var(--shadow-sm);
|
||||
cursor: pointer;
|
||||
transition: background-color var(--transition-fast);
|
||||
|
||||
&:active {
|
||||
background: var(--color-border-light);
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
background: var(--color-primary-bg);
|
||||
margin: 0 auto 8px;
|
||||
}
|
||||
|
||||
.feature-label {
|
||||
font-size: 14px;
|
||||
color: var(--color-text-regular);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user