瀏覽代碼

页面基础框架

DESKTOP-NE65RNK\Citrus_limon 1 年之前
父節點
當前提交
fce21dbef1

文件差異過大導致無法顯示
+ 1233 - 100
package-lock.json


+ 7 - 2
package.json

@@ -9,12 +9,17 @@
     "preview": "vite preview"
     "preview": "vite preview"
   },
   },
   "dependencies": {
   "dependencies": {
-    "vue": "^3.3.11"
+    "@layui/layui-vue": "^2.13.0",
+    "vue": "^3.3.11",
+    "vue-router": "^4.2.5"
   },
   },
   "devDependencies": {
   "devDependencies": {
+    "@types/node": "^20.10.6",
     "@vitejs/plugin-vue": "^4.5.2",
     "@vitejs/plugin-vue": "^4.5.2",
+    "sass": "^1.69.7",
+    "sass-loader": "^13.3.3",
     "typescript": "^5.2.2",
     "typescript": "^5.2.2",
     "vite": "^5.0.8",
     "vite": "^5.0.8",
     "vue-tsc": "^1.8.25"
     "vue-tsc": "^1.8.25"
   }
   }
-}
+}

+ 17 - 4
src/App.vue

@@ -1,7 +1,20 @@
-<script setup lang="ts"></script>
-
 <template>
 <template>
-  <div></div>
+  <router-view class="app-page-wp" />
 </template>
 </template>
 
 
-<style scoped></style>
+<script lang="ts" setup></script>
+
+<style lang="scss">
+@import "./assets/css/index.scss";
+.app-page-wp {
+  position: relative;
+  display: flex;
+  min-height: 100%;
+  width: 100%;
+  .app-page-content {
+    box-sizing: border-box; /*为元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制*/
+    min-height: 100%;
+    width: 100%;
+  }
+}
+</style>

+ 17 - 0
src/assets/css/index.scss

@@ -0,0 +1,17 @@
+* {
+  padding: 0;
+  margin: 0;
+}
+body {
+  font-size: 14px;
+  color: rgba(51, 51, 51, 0.88);
+}
+html,
+body,
+#app {
+  height: 100%;
+}
+
+.hidden {
+  display: none;
+}

+ 67 - 0
src/components/PageLayout/Header.vue

@@ -0,0 +1,67 @@
+<template>
+  <div class="header-wp">
+    <div class="header-left-wp">
+      <div class="title">两江资本</div>
+      <div class="sub-title">无敌中控</div>
+    </div>
+    <div class="header-right-wp">
+      <div class="info-wp">
+        <div class="info-name">欢迎, 成明</div>
+        <div class="info-avatar">
+          <img src="https://www.fmz.cn/upload/asset/54c5a270be79fc941fcb.png" />
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+import { ref } from "vue";
+</script>
+<style lang="scss" scoped>
+.header-wp {
+  box-sizing: border-box;
+  height: 100%;
+  width: 100%;
+  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+  display: flex;
+  .header-left-wp {
+    box-sizing: border-box;
+    display: flex;
+    justify-content: center;
+    flex-direction: column;
+    text-align: center;
+    width: 256px;
+    border-right: 1px solid rgba(0, 0, 0, 0.1);
+    .title {
+      font-size: 18px;
+      font-weight: bold;
+    }
+    .sub-title {
+      font-weight: bold;
+    }
+  }
+  .header-right-wp {
+    flex: 1;
+    display: flex;
+    justify-content: right;
+    align-items: center;
+    .info-wp {
+      display: flex;
+      align-items: center;
+      padding: 0 20px;
+      .info-name {
+        padding-right: 10px;
+        font-size: 14px;
+      }
+      .info-avatar {
+        font-size: 0;
+        img {
+          border-radius: 50%;
+          width: 32px;
+          height: 32px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 48 - 0
src/components/PageLayout/Layout.vue

@@ -0,0 +1,48 @@
+<template>
+  <lay-layout class="layout-wp">
+    <lay-header class="layout-header">
+      <Header />
+    </lay-header>
+    <lay-layout>
+      <lay-side class="layout-side">
+        <Side />
+      </lay-side>
+      <lay-body class="layout-body">
+        <Tag />
+        <div class="layout-main">
+          <router-view class="layout-content" />
+        </div>
+      </lay-body>
+    </lay-layout>
+  </lay-layout>
+</template>
+
+<script lang="ts" setup>
+import Header from "./Header.vue";
+import Side from "./Side.vue";
+import Tag from "./tag.vue";
+import { ref } from "vue";
+</script>
+<style lang="scss" scoped>
+.layout-wp {
+  min-width: 765px;
+  height: 100%;
+  :deep(.layout-header) {
+    height: 64px;
+  }
+  :deep(.layout-side) {
+    flex: 0 0 256px !important;
+    width: 256px !important;
+  }
+  .layout-body {
+    background-color: rgb(244, 246, 247);
+    .layout-main {
+      min-height: calc(100% - 51px);
+      .layout-content {
+        width: 100%;
+        height: 100%;
+      }
+    }
+  }
+}
+</style>

+ 80 - 0
src/components/PageLayout/Side.vue

@@ -0,0 +1,80 @@
+<template>
+  <div class="side-wp">
+    <lay-menu class="menu-wp" v-model:selected-key="selectedKey" theme="light" v-model:openKeys="openKeys4" :tree="true">
+      <lay-menu-item id="1">
+        <template #title>
+          <lay-icon type="layui-icon-console" />
+          控制中心
+        </template>
+      </lay-menu-item>
+      <lay-sub-menu id="2">
+        <template #title>
+          <lay-icon type="layui-icon-set" />
+          系统管理
+        </template>
+        <lay-menu-item id="3">
+          <span class="child-menu">页面管理</span>
+        </lay-menu-item>
+        <lay-menu-item id="4">
+          <span class="child-menu">用户管理</span>
+        </lay-menu-item>
+        <lay-menu-item id="5">
+          <span class="child-menu">组织管理</span>
+        </lay-menu-item>
+      </lay-sub-menu>
+    </lay-menu>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref } from "vue";
+
+const openKeys4 = ref(["2"]);
+const selectedKey = ref("1");
+</script>
+<style lang="scss" scoped>
+.side-wp {
+  box-sizing: border-box;
+  overflow: hidden;
+  height: 100%;
+  width: 100%;
+  border-right: 1px solid rgba(0, 0, 0, 0.1);
+  .menu-wp {
+    box-sizing: border-box;
+    padding: 0;
+    width: auto;
+  }
+  :deep(.layui-nav-tree) {
+    .layui-this {
+      position: relative;
+      a {
+        background-color: rgb(232, 252, 247) !important;
+        border-right: 2px solid rgb(28, 175, 131) !important;
+        &::after {
+          content: "";
+          position: absolute;
+          width: 8px;
+          height: 8px;
+          z-index: 1;
+          transform: rotate(45deg) translateY(-50%);
+          transform-origin: center;
+          border-top: 1px solid rgb(28, 175, 131) !important;
+          border-right: 1px solid rgb(28, 175, 131) !important;
+          right: 20px;
+          top: 50%;
+        }
+        span,
+        i {
+          color: rgb(28, 175, 131) !important;
+        }
+      }
+    }
+    .layui-nav-child {
+      padding: 0;
+    }
+  }
+  .child-menu {
+    padding-left: 14px;
+  }
+}
+</style>

+ 34 - 0
src/components/PageLayout/Tag.vue

@@ -0,0 +1,34 @@
+<template>
+  <div class="tag-wp">
+    <div class="tag-list">
+      <lay-tag class="tag-item" maxWidth="100px" size="lg">
+        <lay-icon type="layui-icon-home" />
+      </lay-tag>
+      <lay-tag class="tag-item" closable maxWidth="100px" size="lg"> 页面管理 </lay-tag>
+      <lay-tag class="tag-item" closable maxWidth="100px" size="lg"> 其他菜单 </lay-tag>
+      <lay-tag class="tag-item" closable maxWidth="100px" size="lg"> 其他菜单 </lay-tag>
+      <lay-tag class="tag-item" closable maxWidth="100px" size="lg"> 其他菜单 </lay-tag>
+      <lay-tag class="tag-item" closable maxWidth="100px" size="lg"> 其他菜单 </lay-tag>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref } from "vue";
+</script>
+<style lang="scss" scoped>
+.tag-wp {
+  background: white;
+  width: 100%;
+  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+  .tag-list {
+    padding: 10px;
+    .tag-item {
+      margin-right: 10px;
+      .layui-icon {
+        font-size: 16px;
+      }
+    }
+  }
+}
+</style>

+ 9 - 3
src/main.ts

@@ -1,4 +1,10 @@
-import { createApp } from 'vue'
-import App from './App.vue'
+import { createApp } from "vue";
+import Layui from "@layui/layui-vue";
+import "@layui/layui-vue/lib/index.css";
+import { router } from "./router";
+import App from "./App.vue";
 
 
-createApp(App).mount('#app')
+const app = createApp(App);
+app.use(Layui);
+app.use(router);
+app.mount("#app");

+ 1 - 0
src/modules-vue.d.ts

@@ -0,0 +1 @@
+declare module '@layui/layui-vue'

+ 7 - 0
src/router/index.ts

@@ -0,0 +1,7 @@
+import { createRouter, createWebHistory } from "vue-router";
+import routes from "./routes";
+
+export const router = createRouter({
+  history: createWebHistory(),
+  routes,
+});

+ 58 - 0
src/router/routes.ts

@@ -0,0 +1,58 @@
+import { RouteRecordRaw } from "vue-router";
+
+const routes: Array<RouteRecordRaw> = [
+  {
+    path: "",
+    redirect: "/dashboard",
+  },
+  {
+    path: "/",
+    name: "Dashboard",
+    component: () => import("@/components/PageLayout/Layout.vue"),
+    meta: { title: "布局页面" },
+    children: [
+      {
+        path: "/dashboard",
+        name: "Dashboard",
+        component: () => import("@/views/dashboard/index.vue"),
+        meta: { title: "仪表盘" },
+      },
+      {
+        path: "/system/user",
+        name: "SystemUser",
+        component: () => import("@/views/system/user/index.vue"),
+        meta: { title: "用户管理" },
+      },
+      {
+        path: "/system/webpage",
+        name: "SystemWebpage",
+        component: () => import("@/views/system/webpage/index.vue"),
+        meta: { title: "用户管理" },
+      },
+      {
+        path: "/system/organization",
+        name: "SystemOrganization",
+        component: () => import("@/views/system/organization/index.vue"),
+        meta: { title: "用户管理" },
+      },
+    ],
+  },
+  {
+    path: "/login",
+    name: "Login",
+    component: () => import("@/views/login/index.vue"),
+    meta: { title: "登录" },
+  },
+  {
+    path: "/404",
+    name: "404",
+    component: () => import("@/views/404.vue"),
+    meta: { title: "404" },
+  },
+  {
+    path: "/:pathMatch(.*)",
+    redirect: "/404",
+  },
+];
+
+export default routes;

+ 5 - 0
src/views/404.vue

@@ -0,0 +1,5 @@
+<template>
+  <div>123123</div>
+</template>
+
+<script lang="ts" setup></script>

+ 16 - 0
src/views/dashboard/index.vue

@@ -0,0 +1,16 @@
+<template>
+  <div class="card-container">
+    <lay-card title="标题"> 内容 </lay-card>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref } from "vue";
+</script>
+
+<style>
+.card-container {
+  background: whitesmoke;
+  padding: 20px;
+}
+</style>

+ 5 - 0
src/views/login/index.vue

@@ -0,0 +1,5 @@
+<template>
+  <div></div>
+</template>
+
+<script lang="ts" setup></script>

+ 5 - 0
src/views/system/organization/index.vue

@@ -0,0 +1,5 @@
+<template>
+  <div></div>
+</template>
+
+<script lang="ts" setup></script>

+ 5 - 0
src/views/system/user/index.vue

@@ -0,0 +1,5 @@
+<template>
+  <div></div>
+</template>
+
+<script lang="ts" setup></script>

+ 5 - 0
src/views/system/webpage/index.vue

@@ -0,0 +1,5 @@
+<template>
+  <div></div>
+</template>
+
+<script lang="ts" setup></script>

+ 7 - 1
src/vite-env.d.ts

@@ -1 +1,7 @@
-/// <reference types="vite/client" />
+declare module "*.vue" {
+  import { App, defineComponent } from "vue";
+  const component: ReturnType<typeof defineComponent> & {
+    install(app: App): void;
+  };
+  export default component;
+}

+ 4 - 0
tsconfig.json

@@ -13,6 +13,10 @@
     "isolatedModules": true,
     "isolatedModules": true,
     "noEmit": true,
     "noEmit": true,
     "jsx": "preserve",
     "jsx": "preserve",
+    "baseUrl": "./",
+    "paths": {
+      "@/*": ["src/*"]
+    },
 
 
     /* Linting */
     /* Linting */
     "strict": true,
     "strict": true,

+ 9 - 3
vite.config.ts

@@ -1,7 +1,13 @@
-import { defineConfig } from 'vite'
-import vue from '@vitejs/plugin-vue'
+import { defineConfig } from "vite";
+import vue from "@vitejs/plugin-vue";
+import { resolve } from "path";
 
 
 // https://vitejs.dev/config/
 // https://vitejs.dev/config/
 export default defineConfig({
 export default defineConfig({
   plugins: [vue()],
   plugins: [vue()],
-})
+  resolve: {
+    alias: {
+      "@": resolve(__dirname, "./src"),
+    },
+  },
+});

部分文件因文件數量過多而無法顯示