初始化

工具版本

  • nodejs:v18.14.2
  • npm:9.5.0

创建 vue-admin 项目

vue 项目 create

 1pnpm create vue@latest
 2 Project name: ... demo
 3? Add TypeScript? » No / Yes
 4√ Add TypeScript? ... No / Yes
 5? Add JSX Support? » No / Yes
 6√ Add JSX Support? ... No / Yes
 7? Add Vue Router for Single Page Application development? » No / Yes
 8√ Add Vue Router for Single Page Application development? ... No / Yes
 9? Add Pinia for state management? » No / Yes
10√ Add Pinia for state management? ... No / Yes
11? Add Vitest for Unit Testing? » No / Yes
12√ Add Vitest for Unit Testing? ... No / Yes
13? Add an End-to-End Testing Solution? » - Use arrow-keys. Return to submit.
14>   No
15    Cypress
16    Playwright
17
18√ Add an End-to-End Testing Solution? » No
19? Add ESLint for code quality? » No / Yes
20√ Add ESLint for code quality? ... No / Yes
21
22cd vue-admin
23pnpm i
24pnpm dev

这里安装的组件有 TypeScript、JSX、Vue Router、Pinia 打开 url http://localhost:5173/ 即可看到效果

配置 vite 文件更新监听

 1export default defineConfig({
 2  server: {
 3    watch: {usePolling:true},
 4    hmr:true
 5  },
 6  plugins: [
 7    vue(), vueJsx(),
 8  ],
 9  resolve: {
10    alias: {
11      '@': fileURLToPath(new URL('./src', import.meta.url))
12    }
13  }
14})

安装 element-plus

1npm install element-plus --save

导入文档:https://element-plus.org/zh-CN/guide/quickstart.html

配置 Volar 支持 配置按需导入

黑暗模式

https://element-plus.org/zh-CN/guide/dark-mode.html

1// main.ts // 如果只想导入css变量 import
2'element-plus/theme-chalk/dark/css-vars.css'

引入 icon

https://element-plus.org/zh-CN/component/icon.html 在这里遇到了 Object.entries 方法不存在的情况需要在 tsconfig.json 的 compilerOptions 字段中增加

 1{
 2  "compilerOptions": {
 3    ...
 4    "lib": [
 5      "esnext",
 6      "dom"
 7    ],
 8    ...
 9  },
10}

tsconfig.json 配置详解参考:https://rushui.net/posts/tsconfig-json/

 1  <svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1"
 2      xmlns="http://www.w3.org/2000/svg">
 3      <path d="M0 0h1024v1024H0V0z" fill="#202425" opacity=".01" />
 4      <path
 5          d="M743.867733 102.4a17.066667 17.066667 0 0 1 12.049067 4.983467l256.750933 256.750933a17.066667 17.066667 0 0 1 0.7168 23.3472L524.8 941.226667a17.066667 17.066667 0 0 1-25.6 0L10.615467 387.4816a17.066667 17.066667 0 0 1 0.7168-23.3472l256.750933-256.750933A17.066667 17.066667 0 0 1 280.132267 102.4h463.735466z"
 6          fill="#11AA66" />
 7      <path
 8          d="M499.165867 360.789333L278.016 108.066133A3.413333 3.413333 0 0 1 280.576 102.4h462.848a3.413333 3.413333 0 0 1 2.56 5.666133l-221.149867 252.7232a17.066667 17.066667 0 0 1-25.668266 0z"
 9          fill="#FFAA44" />
10      <path
11          d="M250.606933 383.8976a34.133333 34.133333 0 0 1 48.128 3.242667L512 630.852267l213.230933-243.712a34.133333 34.133333 0 0 1 51.4048 44.919466l-238.933333 273.066667a34.133333 34.133333 0 0 1-51.4048 0l-238.933333-273.066667a34.133333 34.133333 0 0 1 3.242666-48.128z"
12          fill="#FFFFFF" />
13  </svg>

框架与样式

初始化样式

保留src\assets\main.css文件,其余删除,并增加以下初始样式

 1body {
 2  font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
 3    "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
 4  -webkit-font-smoothing: antialiased;
 5  -moz-osx-font-smoothing: grayscale;
 6  margin: 0;
 7  padding: 0;
 8  height: 100%;
 9}
10
11a {
12  color: var(--ep-color-primary);
13  text-decoration: none;
14}
15
16:root {
17  --el-menu-item-height: 48px;
18  --el-header-height: initial;
19}
20
21code {
22  border-radius: 2px;
23  padding: 2px 4px;
24  background-color: var(--ep-color-primary-light-9);
25  color: var(--ep-color-primary);
26}

模板 layout

修改或新增的相关文件为:

  • src/App.vue
  • src/layouts/Sidecar.vue
  • src/layouts/Header.vue
  • src/layouts/Footer.vue
  • src/layouts/TagView.vue

App.vue

 1<template>
 2  <el-container>
 3    <Sicecar />
 4    <el-container>
 5      <el-header>
 6        <Header />
 7      </el-header>
 8      <el-main>
 9        <RouterView></RouterView>
10      </el-main>
11      <Footer />
12    </el-container>
13  </el-container>
14</template>
15
16<script setup lang="ts">
17import Sicecar from "./layouts/Sidecar.vue";
18import Header from "./layouts/Header.vue";
19import Footer from "./layouts/Footer.vue";
20</script>

Sidecar.vue

  1<template>
  2  <el-aside :class="collapse.collapse ? 'el-aside--collapse' : ''">
  3    <el-menu
  4      default-active="2"
  5      class="el-menu-aside"
  6      :collapse="collapse.collapse"
  7      :router="true"
  8      @open="handleOpen"
  9      background-color="#545c64"
 10      text-color="#fff"
 11      active-text-color="#ffd04b"
 12      @close="handleClose"
 13    >
 14      <div class="logo">
 15        <el-icon>
 16          <IconLogo />
 17        </el-icon>
 18        <span v-if="!collapse.collapse"> 后台管理系统 </span>
 19      </div>
 20      <el-menu-item index="/">
 21        <el-icon><icon-menu /></el-icon>
 22        <template #title> 控制台 </template>
 23      </el-menu-item>
 24      <el-menu-item index="/about">
 25        <el-icon>
 26          <document />
 27        </el-icon>
 28        <template #title> 文档列表 </template>
 29      </el-menu-item>
 30      <el-sub-menu index="3">
 31        <template #title>
 32          <el-icon>
 33            <location />
 34          </el-icon>
 35          <span>用户中心</span>
 36        </template>
 37        <el-menu-item-group>
 38          <template #title><span>用户</span></template>
 39          <el-menu-item index="1-1">用户列表</el-menu-item>
 40          <el-menu-item index="1-2">用户画像</el-menu-item>
 41        </el-menu-item-group>
 42        <el-menu-item-group title="商家">
 43          <el-menu-item index="1-3">商家列表</el-menu-item>
 44        </el-menu-item-group>
 45        <el-sub-menu index="1-4">
 46          <template #title><span>管理员</span></template>
 47          <el-menu-item index="1-4-1">管理员列表</el-menu-item>
 48        </el-sub-menu>
 49      </el-sub-menu>
 50      <el-menu-item index="4">
 51        <el-icon>
 52          <setting />
 53        </el-icon>
 54        <template #title>系统设置</template>
 55      </el-menu-item>
 56    </el-menu>
 57  </el-aside>
 58</template>
 59
 60<script lang="ts" setup>
 61import { useCollapseStore } from "@/stores/collapse";
 62import {
 63  Document,
 64  Menu as IconMenu,
 65  Location,
 66  Setting,
 67} from "@element-plus/icons-vue";
 68import IconLogo from "../components/icons/iconLogo.vue";
 69const collapse = useCollapseStore();
 70const handleOpen = (key: string, keyPath: string[]) => {
 71  console.log(key, keyPath);
 72};
 73const handleClose = (key: string, keyPath: string[]) => {
 74  console.log(key, keyPath);
 75};
 76</script>
 77
 78<style scoped>
 79.logo {
 80  color: #dcdfe6;
 81  text-align: center;
 82  height: 48px;
 83  border-bottom: 0px solid #dcdfe6;
 84}
 85
 86.logo .el-icon {
 87  font-size: 26px;
 88  margin-top: 10px;
 89  margin-bottom: 10px;
 90}
 91
 92.logo span {
 93  margin-left: 10px;
 94  display: inline-block;
 95  line-height: 30px;
 96  vertical-align: super;
 97}
 98
 99.el-menu-aside {
100  height: 100%;
101  min-height: 100vh;
102  display: flex;
103  flex-direction: column;
104  overflow: hidden auto;
105}
106
107.el-aside {
108  width: var(--ep-aside-width, 200px);
109}
110
111.el-aside--collapse {
112  width: var(--ep-aside-width, 65px);
113}
114</style>

Header.vue

 1<template>
 2  <el-header>
 3    <el-menu
 4      :default-active="activeIndex"
 5      class="el-menu-header"
 6      mode="horizontal"
 7      :ellipsis="false"
 8      @select="handleSelect"
 9    >
10      <div class="el-collapse-icon">
11        <a @click="collapse.change()">
12          <el-icon v-if="collapse.collapse">
13            <Expand />
14          </el-icon>
15          <el-icon v-else>
16            <Fold />
17          </el-icon>
18        </a>
19      </div>
20      <div class="flex-grow" />
21      <el-menu-item index="1">
22        <RouterLink to="/">首页</RouterLink>
23      </el-menu-item>
24      <el-menu-item index="2">
25        <RouterLink to="/about">关于</RouterLink>
26      </el-menu-item>
27      <div class="dark-icon" @click="toggleDark()">
28        <el-icon>
29          <Moon v-if="isDark" />
30          <Sunny v-else />
31        </el-icon>
32      </div>
33      <el-sub-menu index="100">
34        <template #title>
35          <el-icon>
36            <Avatar />
37          </el-icon>
38          管理员
39        </template>
40        <el-menu-item index="100-1">个人中心</el-menu-item>
41        <el-menu-item index="100-2">退出</el-menu-item>
42      </el-sub-menu>
43    </el-menu>
44  </el-header>
45</template>
46
47<script lang="ts" setup>
48import { ref } from "vue";
49import { Expand, Fold, Moon, Sunny, Avatar } from "@element-plus/icons-vue";
50import { useCollapseStore } from "@/stores/collapse";
51import { toggleDark, isDark } from "@/stores/dark";
52const collapse = useCollapseStore();
53const activeIndex = ref("1");
54const handleSelect = (key: string, keyPath: string[]) => {
55  console.log(key, keyPath);
56};
57</script>
58
59<style>
60.el-header {
61  --el-header-padding: 0;
62  --el-header-height: initial;
63}
64
65.el-menu-header a {
66  font-size: 14px;
67  font-weight: 500;
68}
69
70.el-collapse-icon a {
71  margin: 15px;
72  font-size: 20px;
73  line-height: 50px;
74}
75
76.dark-icon {
77  font-size: 20px;
78  margin-top: 15px;
79  cursor: pointer;
80}
81
82.flex-grow {
83  flex-grow: 1;
84}
85</style>

Footer.vue

 1<template>
 2  <el-footer>
 3    <div>©2023</div>
 4  </el-footer>
 5</template>
 6
 7<style scoped>
 8.el-footer {
 9  line-height: 48px;
10  vertical-align: middle;
11  height: 48px;
12  border-top: 1px solid #dcdfe6;
13}
14</style>

发布日期:2000-03-05 01:52 字数:1066 用时 6分钟
tags:Vue