- 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)
126 lines
2.6 KiB
Vue
126 lines
2.6 KiB
Vue
<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>
|