Vue3+Element Plus后台项目框架
Vue3+Element Plus后台项目框架
本篇文档在Vue3+Element Plus前端项目模板基础上,增加路由、菜单导航、登录、导航等基础功能
处理布局
整体布局


src/components/layout/AppLayout.vue
<template>
<div class="common-layout">
<el-container>
<el-aside width="200px">Aside</el-aside>
<el-container>
<el-header>Header</el-header>
<el-main>Main</el-main>
</el-container>
</el-container>
</div>
</template>
<style scoped></style>
src/views/HomeView.vue
<script setup lang="ts">
import AppLayout from '@/components/layout/AppLayout.vue'
</script>
<template>
<AppLayout />
</template>
效果

处理布局侧边栏
src/stores/layout/isCollapse.ts
export const isCollapse = ref(false)
src/components/layout/AppAside.vue
<script setup lang="ts">
import { isCollapse } from '@/stores/layout/isCollapse'
import { useRoute } from 'vue-router'
const route = useRoute()
const activeIndex = computed(() => {
const index = route.matched?.[2]?.path
console.log('matched index', index)
return index
})
</script>
<template>
<el-aside>
<!-- 1. router: 开启菜单路由 点击后路由到el-menu-item index地址 unique-opened:保证最多只有一个菜单是打开状态 default-active: 选中的子菜单 不能是sub-menu -->
<el-menu router unique-opened :collapse="isCollapse" :default-active="activeIndex">
<a class="logo" href="/">
<img src="@/assets/favicon.ico" fit="cover" />
<h1 v-show="!isCollapse">管理后台</h1>
</a>
<el-sub-menu index="/1">
<template #title>
<el-icon><IEpLocation /></el-icon>
<span>菜单栏1</span>
</template>
<el-menu-item index="/1/table">子菜单1</el-menu-item>
<el-menu-item index="/1/tree">子菜单2</el-menu-item>
</el-sub-menu>
<el-sub-menu index="/2">
<template #title>
<el-icon><IEpLocation /></el-icon>
<span>菜单栏2</span>
</template>
<el-menu-item index="/2/1">子菜单1</el-menu-item>
<el-menu-item index="/2/2">子菜单2</el-menu-item>
</el-sub-menu>
</el-menu>
</el-aside>
</template>
<style scoped>
.el-aside {
#dedfe0;
height: 100vh;
width: auto;
/* flex布局对其中的menu生效,如果不是flex,menu撑不满 */
display: flex;
}
.el-menu {
#dedfe0;
/* 3. 菜单栏右侧1px的边界去掉 */
border-right: none;
width: 200px;
&.el-menu--collapse {
width: 60px;
}
}
.el-menu-item {
#dedfe0;
}
.logo {
height: 60px;
display: flex;
align-items: center;
justify-content: center;
/* 2. 去掉 a 链接的下划线 */
text-decoration: none;
color: black;
& img {
width: 20px;
height: 20px;
}
}
</style>
src/components/layout/AppLayout.vue
<script setup lang="ts">
import AppAside from '@/components/layout/AppAside.vue'
</script>
<template>
<div class="common-layout">
<el-container>
<AppAside />
<el-container>
<el-header>Header</el-header>
<el-main>Main</el-main>
</el-container>
</el-container>
</div>
</template>
<style scoped></style>
处理布局Header
src/components/layout/AppAside.vue
<script setup lang="ts">
import { isCollapse } from '@/stores/layout/isCollapse'
</script>
<template>
<el-header>
<!-- 展开 折叠的icon -->
<el-icon class="collapse-icon">
<IEpFold v-show="!isCollapse" @click="isCollapse = !isCollapse" />
<IEpExpand v-show="isCollapse" @click="isCollapse = !isCollapse" />
</el-icon>
<!-- 面包屑导航 -->
<el-breadcrumb separator="/">
<el-breadcrumb-item v-for="(item, index) in $route.matched" :key="index">{{
item.meta.title
}}</el-breadcrumb-item>
</el-breadcrumb>
<!-- 下拉框 -->
<el-dropdown>
<span class="el-dropdown-link">
<el-avatar :size="30" src="https://i.imgur.com/yXOvdOSs.jpg" />
<el-icon class="el-icon--right">
<IEpArrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item>
<el-dropdown-item disabled>Action 4</el-dropdown-item>
<el-dropdown-item divided>Action 5</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-header>
</template>
<style scoped>
.el-header {
display: flex;
align-items: center;
#e9e9eb;
}
.collapse-icon {
/* icon 在header中 受整体高度的约束 */
margin-right: 15px;
}
.el-dropdown {
/* 该元素推到其容器的最右边的效果。这通常用于实现将元素右对齐的布局 */
margin-left: auto;
}
.el-dropdown-link {
display: flex;
align-items: center;
}
</style>

处理布局Main区域
src/components/layout/AppLayout.vue
<script setup lang="ts">
import AppAside from '@/components/layout/AppAside.vue'
import AppHeader from '@/components/layout/AppHeader.vue'
</script>
<template>
<div>
<el-container>
<AppAside />
<el-container class="header-and-main">
<AppHeader />
<el-main>
<!-- 打洞slot 避免页面太大撑爆了,加滚动条 -->
<el-scrollbar>
<RouterView />
</el-scrollbar>
</el-main>
</el-container>
</el-container>
</div>
</template>
<style scoped>
.header-and-main {
/* header和main在一个contain中 纵向排布 */
flex-direction: column;
height: 100vh;
}
.el-main {
#f4f4f5;
}
</style>
基本功能性页面
表格
src/views/TableView.vue
<script setup lang="ts">
import { isDialogFormVisible } from '@/stores/table/isDialogFormVisible'
import CreaeteTableDialog from '@/components/table/CreateTableDialog.vue'
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}
]
</script>
<template>
<el-card class="box-card">
<template #header>
<div class="card-header">
<span>表格名称</span>
<el-button @click="isDialogFormVisible = true" class="button" type="primary" size="large"
>创建</el-button
>
</div>
</template>
<!-- 创建弹窗 -->
<CreaeteTableDialog />
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="Date" width="180"

