02.使用Vue3集成Element-Plus快速搭建一个管理系统的页面框架

Element-Plus 简介

Element-Plus 是一套前端UI框架,非常适合前端基础比较差的同学,可以通过它快速实现精美的页面样式

官网: https://element-plus.org

国内镜像网站(访问速度快): https://cn.element-plus.org/

Vue3 集成Element-Plus

安装依赖

1
npm i element-plus -S

image-20250227112206924.png

写在element-plus

1
npm uninstall element-plus

node_modules 可以查看

在main.js里面引入

1
2
3
4
5
6
7
mport ElmentPlus from 'element-plus'
import 'element-plus/dist/index.css'
import zhCn from 'element-plus/es/locale/lang/zh-cn'

app.use(ElmentPlus,{
locale: zhCn,
})

在Home.vue中测试一下: 使用官方按钮组件

1
2
3
4
5
6
7
8
9
10
11
<template>
<div class="mb-4">
<el-button>Default</el-button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
</div>

</template>

全局使用 icon

安装依赖,注册所有图标

1
npm install @element-plus/icons-vue
1
2
3
<script setup> setup不能忘!!!

</script>

在main.js里引入

1
2
3
4
5
6
7
8
9
// main.ts

// 如果您正在使用CDN引入,请删除下面一行。
import * as ElementPlusIconsVue from '@element-plus/icons-vue'

const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}

使用图标: el-icon,el-input,el-button

当你在按钮或者输入框组件里面使用图标,你需要单独导入图标 直接按alt+enter 导入即可

按钮或者图标组件里面,不需要单独导入图标

Element-Plus 主题色设置

官网的指南==>主题有详细讲解

安装依赖 sass,unplugin-vue-components,unplugin-auto-import

1
npm install -D sass unplugin-vue-component unplugin-auto-import

配置index.scss 放在src/assets/css目录下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* just override what you need */
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'primary': ("base": #2c82ff),
'success': ("base": #31bf00),
'warning': ("base": #ffad00),
'danger': ("base": #e52f2f),
'info': ("base": #8055ff),
)
);

// If you just import on demand, you can ignore the following content.
// 如果你想导入所有样式:
// @use "element-plus/theme-chalk/src/index.scss" as *;

配置vite.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { fileURLToPath } from 'node:url' // 新增导入

export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: `
@use "@/assets/css/index.scss" as *;
`,
}
}
},
plugins: [
vue(),
vueDevTools(),
//element-plus按需导入
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
// 配置elementPlus采用sass样式配置系统
resolvers: [ElementPlusResolver({ importStyle: 'sass' })]
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})

安装 element插件

直接在插件搜索即可

路由嵌套:

Manager.vue

1
2
3
4
5
6
7
8
9
10
11
<template>
<div>
这是父组件
<!-- 路由嵌套 -->
<RouterView />
</div>
</template>

<script setup>

</script>

index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{path: '/manager', name: 'home', component: import('../views/Manager.vue'),
children: [
{path: 'home', component: import('../views/Home.vue'),},
]},
{path: '/about', component: import('../views/About.vue'),},
{path: '/notFound', component: import('../views/404.vue'),},
{path: '/:pathMatch(.*)',redirect: '/notFound'}
],
})

export default router

Home.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div class="mb-4">
<el-button>Default</el-button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>

<div style="padding: 50px">
<el-icon size="25" color="red"><Finished /></el-icon>
</div>

</div>

</template>

<script setup>

</script>

效果:

image-20250227170327050.png

搭建后台基本框架

image-20250227170014902.png

头部区域

1
2
3
4
5
6
7
8
9
10
11
<!--头部区域开始-->
<div style="height: 60px; display: flex; align-items: center; border-bottom: 1px solid #eee" >
<div style="display: flex; align-items: center;padding-left: 20px">
<!-- ctrl+shift+上键 向上-->
<img style="width: 40px; height: 40px;border-radius: 50%" src="../assets/imgs/logo.jpg" alt="">
<span style="font-size: 20px; font-weight: bold; color: #e66dc5;margin-left: 5px">KittenKit Management System</span>
</div>
<div style="flex: 1"></div>
<div></div>
</div>
<!--头部区域结束-->

配置导航菜单

菜单主题颜色:

高亮颜色:

主题区域

配置一个card卡片样式

1
2
3
4
5
6
.card {
background-color: white;
padding: 10px;
border-radius: 5px;
box-shadow: 0 0 8px rgba(0,0,0,.12)
}

可以通过router.currentRoute.value.path 获取当前展示的路由

1
:default-active="router.currentRoute.value.path"

配置标题和Logo区域

Avatar 头像 | Element Plus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div style="width: fit-content; padding-right: 20px;display: flex;align-items: center;border-bottom: 1px solid #ddd">
<el-dropdown>
<div style="display: flex;align-items: center">
<img style="width: 40px; height: 40px; border-radius: 50%" src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" alt="">
<span style="margin-left: 5px">管理员</span>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item>修改密码</el-dropdown-item>
<el-dropdown-item>退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>

笔记内容

global.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
* {
box-sizing: border-box;
}

body {
margin: 0;
padding: 0;
color: #333;
font-size: 14px;
}

a {
text-decoration: none;
}

.card {
background-color: white;
padding: 10px;
border-radius: 5px;
box-shadow: 0 0 8px rgba(0,0,0,.12)
}

Manager.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<template>
<div>
<!--头部区域开始-->
<div style="height: 60px; display: flex; /*align-items: center; border-bottom: 1px solid #eee;*/" >
<div style="width:240px;display: flex; align-items: center;padding-left: 15px; background-color: #eea6ed">
<!-- ctrl+shift+上键 向上-->
<img style="width: 40px; height: 40px;border-radius: 50%" src="../assets/imgs/logo.jpg" alt="">
<span style="font-size: 12px; font-weight: bold; color: #f8f4f7;margin-left: 5px">KittenKit Management System</span>
</div>
<div style="flex: 1; display:flex; align-items:center;border-bottom: 1px solid #ddd; padding-left: 20px">
Home / DataAnalysis
</div>
<div style="width: fit-content; padding-right: 20px;display: flex;align-items: center;border-bottom: 1px solid #ddd">
<el-dropdown>
<div style="display: flex;align-items: center">
<img style="width: 40px; height: 40px; border-radius: 50%" src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" alt="">
<span style="margin-left: 5px">管理员</span>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item>修改密码</el-dropdown-item>
<el-dropdown-item>退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>

</div>
<!--头部区域结束-->


<!-- 下方区域开始 -->
<div style="display: flex">
<!-- 菜单区域开始 -->
<div style="width: 240px; box-shadow: 0 0 8px rgba(0,0,0,.12)">
<!-- :default-openeds="['1']" : 默认展开 -->
<el-menu router :default-active="router.currentRoute.value.path" style="min-height: calc(100vh - 60px)">
<el-menu-item index="/manager/home">
<el-icon><House /></el-icon>
<span>Home</span>
</el-menu-item>
<el-sub-menu index="1">
<template #title>
<el-icon><location /></el-icon>
<span>Data management</span>
</template>
<el-menu-item index="/manager/about">About Data</el-menu-item>
</el-sub-menu>
</el-menu>
</div>
<!-- 菜单区域结束 -->

<!-- 数据渲染区域开始 -->
<div style="flex: 1;width: 0; padding: 10px; background-color: #faf4fa">
<RouterView />
</div>
<!-- 数据渲染区域结束 -->
</div>
<!-- 下方区域结束 -->
</div>
</template>

<script setup>
import router from "@/router/index.js";
</script>

<style>
.el-menu {
background-color: #FFD9E6; /* 主背景改为柔粉红(降低饱和度) */
border: none;
box-shadow: 0 0 8px rgba(0,0,0,.12)
}

.el-sub-menu__title {
background-color: #FFD9E6;
color: #FF6B6B; /* 文字改为柔和的玫瑰粉(提升可读性) */
}

.el-menu-item {
height: 50px;
color: #FF6B6B; /* 统一文字颜色 */
}

.el-menu .is-active {
background-color: #FFE5D9; /* 保持蜜桃奶白背景 */
color: #FF6B6B !important; /* 激活文字改为深玫瑰粉 */
font-weight: 600;
}

.el-sub-menu__title:hover {
background-color: #FFB7C5; /* 悬停改为樱花粉(与主背景形成渐变层次) */
}

.el-menu-item:not(.is-active):hover {
color: #FADADD; /* 保持原有玫瑰粉 */
background-color: #FFE5D9; /* 新增悬停背景(与激活状态呼应) */
}

.el-tooltip__trigger {
outline: none;
}

.el-dropdown {
cursor: pointer;
}


.el-menu-inline .el-menu-item {
padding-left: 48px !important;
}
</style>

HOME.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<template>
<div>
<div class="card" style="margin-bottom: 5px">
<el-input style="width: 240px;margin-right: 5px;" v-model="input" placeholder="请输入名称查询" :prefix-icon="Search"></el-input>
<el-button type="primary">查询</el-button>
</div>

<div class="card" style="margin-bottom: 5px">
<el-button type="danger">批量删除</el-button>
<el-button type="primary">新 增</el-button>
<el-button type="success">批量导入</el-button>
<el-button type="info">批量导出</el-button>
</div>

<div class="card" style="margin-bottom: 5px">
<el-table :data="data.tableData" style="width: 100%" :header-cell-style="{fontWeight: 'bold',color: '#333',backgroundColor: '#c902f6'}">
<el-table-column prop="name" label="名称" width="180" />
<el-table-column prop="phone" label="电话" />
<el-table-column prop="address" label="地址" width="180" />
</el-table>
</div>

<!-- 分页-->
<div class="card">
<el-pagination
v-model:current-page="data.pageNum"
:page-size="data.pageSize"
layout="total, prev, pager, next"
:total="data.total"

/>


</div>
</div>

</template>

<script setup>
import {reactive} from "vue";
import {Search} from "@element-plus/icons-vue";

const data = reactive({
name: null,
pageNum: 1,
pageSize: 5,
total: 6,
tableData: [
{ name: 'Yangjiayu',phone: '13456789001', address: '北京市海淀区'},
{ name: 'James',phone: '13456789002', address: '上海市徐汇区'},
{ name: 'Luka',phone: '13456789003', address: '安徽省合肥市'},
{ name: 'Dodo',phone: '13456789004', address: '安徽省合肥市'},
{ name: 'Bacun',phone: '13456789005', address: '安徽省合肥市'},
{ name: 'River',phone: '13456789006', address: '安徽省合肥市'},
]
})

</script>

index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{path: '/manager', name: 'home', component: import('../views/Manager.vue'),
children: [
{path: 'home', component: import('../views/Home.vue'),},
{path: 'about', component: import('../views/About.vue'),},
]},
// {path: '/manager/about', component: import('../views/About.vue'),},
{path: '/notFound', component: import('../views/404.vue'),},
{path: '/:pathMatch(.*)',redirect: '/notFound'}
],
})

export default router