ソースを参照

feat: 页面布局及样式处理(Scss & UnoCSS)

simon 9 ヶ月 前
コミット
80aeb602a1

+ 2 - 1
.vscode/extensions.json

@@ -3,6 +3,7 @@
     "dbaeumer.vscode-eslint",
     "esbenp.prettier-vscode",
     "editorconfig.editorconfig",
-    "vue.volar"
+    "vue.volar",
+    "antfu.unocss"
   ]
 }

+ 1 - 1
commitlint.config.cjs

@@ -1,3 +1,3 @@
 module.exports = {
-  extends: ["@commitlint/config-conventional"],
+  extends: ["@commitlint/config-conventional"]
 };

+ 6 - 0
package.json

@@ -12,7 +12,9 @@
     "prepare": "husky"
   },
   "dependencies": {
+    "@unocss/transformer-directives": "66.1.0-beta.7",
     "element-plus": "^2.9.7",
+    "normalize.css": "^8.0.1",
     "pinia": "^3.0.1",
     "vue": "^3.5.13",
     "vue-router": "^4.5.0"
@@ -21,6 +23,8 @@
     "@commitlint/cli": "^19.8.0",
     "@commitlint/config-conventional": "^19.8.0",
     "@eslint/js": "^9.23.0",
+    "@unocss/preset-attributify": "66.1.0-beta.7",
+    "@unocss/preset-uno": "66.1.0-beta.7",
     "@vitejs/plugin-vue": "^5.2.1",
     "@vue/tsconfig": "^0.7.0",
     "eslint": "^9.23.0",
@@ -31,8 +35,10 @@
     "husky": "^9.1.7",
     "lint-staged": "^15.5.0",
     "prettier": "^3.5.3",
+    "sass": "^1.86.0",
     "typescript": "~5.7.2",
     "typescript-eslint": "^8.28.0",
+    "unocss": "66.1.0-beta.7",
     "vite": "^6.2.0",
     "vue-tsc": "^2.2.4"
   },

ファイルの差分が大きいため隠しています
+ 779 - 4
pnpm-lock.yaml


+ 0 - 9
src/App.vue

@@ -1,18 +1,9 @@
 <script setup lang="ts">
 import { RouterView } from "vue-router";
-import { useCounterStore } from "./stores/counter";
-
-const store = useCounterStore();
 </script>
 
 <template>
-  <RouterLink to="/home"> 首页 </RouterLink>
-  <RouterLink to="/about"> 关于 </RouterLink>
-  {{ store.count }}
-  <button @click="store.increment">+</button>
   <RouterView />
-
-  <el-button type="primary">Element Button</el-button>
 </template>
 
 <style scoped>

+ 38 - 0
src/layout/index.vue

@@ -0,0 +1,38 @@
+<template>
+  <div class="app-wrapper">
+    <div class="sidebar-container">侧边导航</div>
+    <div class="main-container">
+      <div class="header">
+        <div class="navbar">导航条1</div>
+        <div class="tags-view">导航条2</div>
+      </div>
+      <div class="app-main">
+        <router-view></router-view>
+      </div>
+    </div>
+  </div>
+</template>
+<style lang="scss">
+.app-wrapper {
+  @apply flex w-full h-full;
+  .sidebar-container {
+    @apply bg-red w-210px;
+  }
+  .main-container {
+    @apply flex flex-col flex-1 h-lvh;
+  }
+  .header {
+    @apply h-84px;
+    .navbar {
+      @apply h-50px bg-yellow;
+    }
+    .tags-view {
+      @apply h-34px bg-blue;
+    }
+  }
+  .app-main {
+    @apply bg-cyan;
+    min-height: calc(100vh - 84px);
+  }
+}
+</style>

+ 4 - 1
src/main.ts

@@ -1,10 +1,13 @@
 import { createApp } from "vue";
-import "./style.css";
 import App from "./App.vue";
+
 import router from "./router";
+import "normalize.css/normalize.css";
 import { createPinia } from "pinia";
 import ElementPlus from "element-plus";
 import "element-plus/dist/index.css";
+import "@/style/index.scss";
+import "uno.css";
 
 const app = createApp(App);
 const pinia = createPinia();

+ 11 - 8
src/router/index.ts

@@ -3,17 +3,20 @@ import {
   createWebHistory,
   type RouteRecordRaw
 } from "vue-router";
+import Layout from "@/layout/index.vue";
 
 const routes: RouteRecordRaw[] = [
   {
-    path: "/home",
-    name: "home",
-    component: () => import("@/views/Home.vue")
-  },
-  {
-    path: "/about",
-    name: "about",
-    component: () => import("@/views/About.vue")
+    path: "/",
+    component: Layout,
+    redirect: "/dashboard",
+    children: [
+      {
+        path: "dashboard",
+        name: "Dashboard",
+        component: () => import("@/views/Dashboard/index.vue")
+      }
+    ]
   }
 ];
 

+ 0 - 10
src/stores/counter.ts

@@ -1,10 +0,0 @@
-import { defineStore } from "pinia";
-import { ref } from "vue";
-
-export const useCounterStore = defineStore("counter", () => {
-  const count = ref(0);
-  const increment = () => {
-    count.value++;
-  };
-  return { count, increment };
-});

+ 0 - 79
src/style.css

@@ -1,79 +0,0 @@
-:root {
-  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
-  line-height: 1.5;
-  font-weight: 400;
-
-  color-scheme: light dark;
-  color: rgba(255, 255, 255, 0.87);
-  background-color: #242424;
-
-  font-synthesis: none;
-  text-rendering: optimizeLegibility;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-}
-
-a {
-  font-weight: 500;
-  color: #646cff;
-  text-decoration: inherit;
-}
-a:hover {
-  color: #535bf2;
-}
-
-body {
-  margin: 0;
-  display: flex;
-  place-items: center;
-  min-width: 320px;
-  min-height: 100vh;
-}
-
-h1 {
-  font-size: 3.2em;
-  line-height: 1.1;
-}
-
-button {
-  border-radius: 8px;
-  border: 1px solid transparent;
-  padding: 0.6em 1.2em;
-  font-size: 1em;
-  font-weight: 500;
-  font-family: inherit;
-  background-color: #1a1a1a;
-  cursor: pointer;
-  transition: border-color 0.25s;
-}
-button:hover {
-  border-color: #646cff;
-}
-button:focus,
-button:focus-visible {
-  outline: 4px auto -webkit-focus-ring-color;
-}
-
-.card {
-  padding: 2em;
-}
-
-#app {
-  max-width: 1280px;
-  margin: 0 auto;
-  padding: 2rem;
-  text-align: center;
-}
-
-@media (prefers-color-scheme: light) {
-  :root {
-    color: #213547;
-    background-color: #ffffff;
-  }
-  a:hover {
-    color: #747bff;
-  }
-  button {
-    background-color: #f9f9f9;
-  }
-}

+ 7 - 0
src/style/index.scss

@@ -0,0 +1,7 @@
+@import "./variables.module.scss";
+
+:root {
+  --sidebar-width: #{$sideBarWidth};
+  --navbar-height: #{$navBarHeight};
+  --tagsview-height: #{$tagsViewHeight};
+}

+ 3 - 0
src/style/variables.module.scss

@@ -0,0 +1,3 @@
+$sideBarWidth: 210px;
+$navBarHeight: 50px;
+$tagsViewHeight: 34px;

+ 0 - 1
src/views/About.vue

@@ -1 +0,0 @@
-<template>About</template>

+ 1 - 0
src/views/Dashboard/index.vue

@@ -0,0 +1 @@
+<template>Dashboard</template>

+ 0 - 5
src/views/Home.vue

@@ -1,5 +0,0 @@
-<template>
-  <div>
-    <h1>Home</h1>
-  </div>
-</template>

+ 9 - 0
uno.config.ts

@@ -0,0 +1,9 @@
+import { defineConfig } from "unocss";
+import presetAttributify from "@unocss/preset-attributify";
+import presetUno from "@unocss/preset-uno";
+import transformerDirectives from "@unocss/transformer-directives";
+
+export default defineConfig({
+  presets: [presetAttributify(), presetUno()],
+  transformers: [transformerDirectives()] // apply
+});

+ 7 - 1
vite.config.ts

@@ -1,6 +1,7 @@
 import { defineConfig } from "vite";
 import vue from "@vitejs/plugin-vue";
 import path from "path";
+import UnoCSS from "unocss/vite";
 
 // https://vite.dev/config/
 export default defineConfig({
@@ -11,5 +12,10 @@ export default defineConfig({
      */
     alias: [{ find: "@", replacement: path.resolve(__dirname, "src") }]
   },
-  plugins: [vue()]
+  plugins: [
+    UnoCSS({
+      configFile: "./UnoCSS.config.ts"
+    }),
+    vue()
+  ]
 });