| | |
| | | const component: FunctionalComponent<SVGAttributes> |
| | | export default component |
| | | } |
| | | declare module '*.vue' { |
| | | import type { DefineComponent } from 'vue' |
| | | // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| | | const component: DefineComponent<object, object, any> |
| | | export default component |
| | | } |
| | |
| | | <meta charset="UTF-8" /> |
| | | <link rel="icon" href="/favicon.ico" /> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| | | <title>Vite App</title> |
| | | <title>看板</title> |
| | | </head> |
| | | <body> |
| | | <div id="app"></div> |
| | |
| | | "version": "0.0.0", |
| | | "private": true, |
| | | "scripts": { |
| | | "dev": "vite --host --open", |
| | | "dev": "vite --host", |
| | | "build": "run-p type-check \"build-only {@}\" --", |
| | | "preview": "vite preview", |
| | | "build-only": "vite build", |
| | |
| | | <template> |
| | | <nav> |
| | | <RouterLink to="/">Home</RouterLink> |
| | | <RouterLink to="/about">About</RouterLink> |
| | | </nav> |
| | | <RouterView /> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { RouterLink, RouterView } from 'vue-router' |
| | | import { RouterView } from 'vue-router' |
| | | </script> |
| | | |
| | | <style scoped> |
| | | nav { |
| | | width: 100%; |
| | | font-size: 24px; |
| | | text-align: center; |
| | | } |
| | | |
| | | nav a.router-link-exact-active { |
| | | color: var(--el-color-primary); |
| | | } |
| | | |
| | | nav a { |
| | | display: inline-block; |
| | | padding: 0 1rem; |
| | | border-left: 1px solid var(--color-border); |
| | | } |
| | | |
| | | nav a:first-of-type { |
| | | border: 0; |
| | | } |
| | | </style> |
| | | <style scoped></style> |
| | |
| | | --vt-c-black-soft: #222222; |
| | | --vt-c-black-mute: #282828; |
| | | |
| | | --vt-c-indigo: #2c3e50; |
| | | --vt-v-blue: #13234b; |
| | | |
| | | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); |
| | | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); |
| | | --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); |
| | | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); |
| | | |
| | | --vt-c-text-light-1: var(--vt-c-indigo); |
| | | --vt-c-text-light-2: rgba(60, 60, 60, 0.66); |
| | | --vt-c-text-dark-1: var(--vt-c-white); |
| | | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); |
| | | } |
| | | |
| | | /* semantic color variables for this project */ |
| | | :root { |
| | | --color-background: var(--vt-c-white); |
| | | --color-background-soft: var(--vt-c-white-soft); |
| | | --color-background-mute: var(--vt-c-white-mute); |
| | | |
| | | --color-border: var(--vt-c-divider-light-2); |
| | | --color-border-hover: var(--vt-c-divider-light-1); |
| | | |
| | | --color-heading: var(--vt-c-text-light-1); |
| | | --color-text: var(--vt-c-text-light-1); |
| | | |
| | | --color-background: var(--vt-v-blue); |
| | | --color-text: var(--vt-c-white); |
| | | --section-gap: 160px; |
| | | } |
| | | |
| | | @media (prefers-color-scheme: dark) { |
| | | :root { |
| | | --color-background: var(--vt-c-black); |
| | | --color-background-soft: var(--vt-c-black-soft); |
| | | --color-background-mute: var(--vt-c-black-mute); |
| | | |
| | | --color-border: var(--vt-c-divider-dark-2); |
| | | --color-border-hover: var(--vt-c-divider-dark-1); |
| | | |
| | | --color-heading: var(--vt-c-text-dark-1); |
| | | --color-text: var(--vt-c-text-dark-2); |
| | | } |
| | | } |
| | | |
| | | *, |
| | |
| | | min-height: 100vh; |
| | | color: var(--color-text); |
| | | background: var(--color-background); |
| | | transition: |
| | | color 0.5s, |
| | | background-color 0.5s; |
| | | line-height: 1.6; |
| | | font-family: |
| | | Inter, |
| | |
| | | @import './base.css'; |
| | | |
| | | #app { |
| | | max-width: 1280px; |
| | | margin: 0 auto; |
| | | |
| | | font-weight: normal; |
| | | /* 覆盖 el 滚动条颜色 */ |
| | | .el-scrollbar .el-scrollbar__thumb{ |
| | | background-color: #fff; |
| | | opacity: 0.5; |
| | | } |
| | | |
| | |
| | | |
| | | declare module 'vue' { |
| | | export interface GlobalComponents { |
| | | DashboardLayout: (typeof import('./components/DashboardLayout.vue'))['default'] |
| | | ElButton: (typeof import('element-plus/es'))['ElButton'] |
| | | ElIcon: (typeof import('element-plus/es'))['ElIcon'] |
| | | HelloWorld: (typeof import('./components/HelloWorld.vue'))['default'] |
| | | ElScrollbar: (typeof import('element-plus/es'))['ElScrollbar'] |
| | | RouterLink: (typeof import('vue-router'))['RouterLink'] |
| | | RouterView: (typeof import('vue-router'))['RouterView'] |
| | | } |
New file |
| | |
| | | <template> |
| | | <div class="dashboard-layout"> |
| | | <div class="left"> |
| | | <div class="header-block padding-4"> |
| | | <slot name="leftBlock1"></slot> |
| | | </div> |
| | | <div class="double-height-block padding-4"> |
| | | <div class="card"> |
| | | <el-scrollbar always> |
| | | <slot name="leftBlock2"></slot> |
| | | </el-scrollbar> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="middle"> |
| | | <div class="header-block padding-4"> |
| | | <slot name="middleBlock1"></slot> |
| | | </div> |
| | | <div class="base-block padding-4"> |
| | | <div class="card"> |
| | | <slot name="middleBlock2"></slot> |
| | | </div> |
| | | </div> |
| | | <div class="block-container"> |
| | | <div class="base-block padding-4"> |
| | | <div class="card"> |
| | | <slot name="middleBlock3"></slot> |
| | | </div> |
| | | </div> |
| | | <div class="base-block padding-4"> |
| | | <div class="card"> |
| | | <slot name="middleBlock4"></slot> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="right"> |
| | | <div class="header-block padding-4"> |
| | | <slot name="rightBlock1"></slot> |
| | | </div> |
| | | <div class="base-block padding-4"> |
| | | <div class="card"> |
| | | <slot name="rightBlock2"></slot> |
| | | </div> |
| | | </div> |
| | | <div class="base-block padding-4"> |
| | | <div class="card"> |
| | | <slot name="rightBlock3"></slot> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"></script> |
| | | |
| | | <style scoped lang="scss"> |
| | | // 两侧区域宽 |
| | | $sideWidth: 25%; |
| | | // 中间主区域宽 |
| | | $mainWidth: 50%; |
| | | // 整体内边距 |
| | | $layoutPadding: 12px; |
| | | // 头部布局块高度 |
| | | $headerBlockHeight: 80px; |
| | | // 基础布局块高度 |
| | | $baseBlockHeight: calc((100vh - 2 * $layoutPadding - $headerBlockHeight) / 2); |
| | | // 双倍高布局块高度 |
| | | $doubleBlockHeight: calc($baseBlockHeight * 2); |
| | | .dashboard-layout { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | height: 100vh; |
| | | width: 100vw; |
| | | padding: $layoutPadding; |
| | | &.debug { |
| | | & > div { |
| | | border: 1px solid red; |
| | | & > div { |
| | | border: 1px solid red; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .left, |
| | | .right { |
| | | width: $sideWidth; |
| | | } |
| | | |
| | | .middle { |
| | | width: $mainWidth; |
| | | } |
| | | .left, |
| | | .right, |
| | | .middle { |
| | | height: 100%; |
| | | } |
| | | .padding-4 { |
| | | padding: 6px; |
| | | } |
| | | .block-container { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | } |
| | | .base-block { |
| | | height: $baseBlockHeight; |
| | | flex-grow: 1; |
| | | } |
| | | .header-block { |
| | | height: $headerBlockHeight; |
| | | } |
| | | .double-height-block { |
| | | height: $doubleBlockHeight; |
| | | } |
| | | |
| | | .card { |
| | | width: 100%; |
| | | height: 100%; |
| | | background-color: #153e94; |
| | | border-radius: 6px; |
| | | } |
| | | </style> |
| | |
| | | import { createRouter, createWebHistory } from 'vue-router' |
| | | import HomeView from '../views/HomeView.vue' |
| | | import DashboardView from '../views/dashboard/index.vue' |
| | | |
| | | const router = createRouter({ |
| | | history: createWebHistory(import.meta.env.BASE_URL), |
| | | routes: [ |
| | | { |
| | | path: '/', |
| | | name: 'home', |
| | | component: HomeView |
| | | name: 'dashboard', |
| | | component: DashboardView |
| | | }, |
| | | { |
| | | path: '/about', |
| | | name: 'about', |
| | | // route level code-splitting |
| | | // this generates a separate chunk (About.[hash].js) for this route |
| | | // which is lazy-loaded when the route is visited. |
| | | component: () => import('../views/AboutView.vue') |
| | | path: '/:error*', |
| | | redirect: '/' |
| | | } |
| | | ] |
| | | }) |
New file |
| | |
| | | <template> |
| | | <DashboardLayout> |
| | | <template #leftBlock1>任务筛选tabs</template> |
| | | <template #leftBlock2> |
| | | <div style="height: 1500px">通道任务</div> |
| | | </template> |
| | | <template #middleBlock1>标题</template> |
| | | <template #middleBlock2>主看板</template> |
| | | <template #middleBlock3>任务详情</template> |
| | | <template #middleBlock4>人员信息</template> |
| | | <template #rightBlock1>时间</template> |
| | | <template #rightBlock2>状态面板</template> |
| | | <template #rightBlock3>知识库</template> |
| | | </DashboardLayout> |
| | | </template> |
| | | <script setup lang="ts"> |
| | | defineOptions({ |
| | | name: 'DashboardView' |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped></style> |