vue3后台管理系统模板
Vue3.0 发布第一个版本至今有一段时间了,到现在一直在更新优化,在性能方面,对比 Vue2.x ,性能的提升比较明显,打包后体积更小
来看下 Vue3.x 新增了哪些功能和特性。
Performance:性能优化
Tree-shaking support:支持摇树优化
Composition API:组合API
Fragment,Teleport,Suspense:新增的组件
Better TypeScript support:更好的TypeScript支持
Custom Renderer API:自定义渲染器
目前和vue3配套的UI组件库相对较完善的因该算 Element Plus(pc端) 和 Vant(移动端)了
vue2.x 和 3.x还是有一些本质上的区别, 反而使用上区别不是太大。有vue2.x基础的伙伴到手可用
这里不说那些单独功能,因为实践出真知,直接附上一个 vue3 + Element Plus 后台管理系统模板
我用目前了解的vue3知识做了一个后台管理系统模板。有兴趣的伙伴可以拿到手直接就可用
1. 用到技术: vue3 + Element Plus + Vuex + Route
2. 技术点: 登录功能 + 页面跳转 + 子路由 + 动态路由 + 菜单栏 + 子菜单(展开和不展开都兼容) + 路由监听 + 路由跳转
内容不复杂,一看就懂,功能不复杂,到手可用
待完善:UI美化 功能根据自己需要完善 适配
项目成品图:

代码:
main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
createApp(App).use(store).use(router).use(ElementPlus).mount('#app')
App.vue
<template>
<router-view/>
</template>
<style lang="scss">
body, html {
background: #696969;
}
* {
padding: 0;margin: 0;
}
</style>
router.js
import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
{
path: '/',
redirect: '/login',
component: () => import('@/views/login')
},
{
path: '/login',
name: 'login',
component: () => import('@/views/login')
},
{
path: '/home',
name: 'home',
component: () => import('@/views/home/home'),
children: [
{path: '/aa', name: 'aa', component: () => import('@/views/home/rightnav/aa')},
{path: '/bb', name: 'bb', component: () => import('@/views/home/rightnav/bb')},
{path: '/cc', name: 'cc', component: () => import('@/views/home/rightnav/cc')},
{path: '/dd', name: 'dd', component: () => import('@/views/home/rightnav/dd')},
{path: '/ee', name: 'ee', component: () => import('@/views/home/rightnav/ee')},
{path: '/ff', name: 'ff', component: () => import('@/views/home/rightnav/ff')},
{path: '/wei1', name: 'wei1', component: () => import('@/views/home/rightnav/wei1')},
]
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
login.vue
<template>
<div class="login">
<el-form
label-width="100px"
:model="formLabelAlign"
style="max-width: 460px"
>
<el-form-item label="账号:">
<el-input v-model="formLabelAlign.name" />
</el-form-item>
<el-form-item label="密码:">
<el-input v-model="formLabelAlign.password" />
</el-form-item>
</el-form>
<el-button type="primary" size="large" style="margin: 100px 0 0 220px;" @click="denglu">登录</el-button>
</div>
</template>
<script>
import { useRouter } from 'vue-router';
import { reactive } from 'vue'
export default {
name: 'login',
setup() {
const $router = useRouter();
const formLabelAlign = reactive({
name: '',
password: '',
})
function denglu() {
console.log("ddd", formLabelAlign.name)
console.log("ddd", formLabelAlign.password)
if(formLabelAlign.name && formLabelAlign.password) {
$router.replace('/home')
}
}
return {formLabelAlign, denglu}
}
}
</script>
<style>
.login {width: 500px;height: 460px;background: #778899;margin: 100px auto;border-radius: 10px;padding: 150px 0 0 0px;box-sizing: border-box;}
</style>
home.vue
<template>
<div>
<el-container style="height: 100vh;">
<el-header class="head"><Top/></el-header>
<el-container>
<el-aside width="200px" class="left"><LeftNav/></el-aside>
<el-main class="right"><router-view/></el-main>
</el-container>
</el-container>
</div>
</template>
<script>
import Top from '@/views/home/top'
import LeftNav from '@/views/home/leftnav'
export default {
components: {Top, LeftNav}
}
</script>
<style>
.head {background: #ccc;}
.left {background: #ddd;}
.right {background: #eee;}
</style>
leftNav.vue
<template>
<el-menu
:default-active="nowPath"
class="el-menu-vertical-demo"
router
unique-opened
active-text-color="#fe4800"
background-color="#fff"
@open="handleOpen"
@close="handleClose"
>
<div v-for="(item) in menu" :key="item" class="elMenu">
<el-menu-item :index="item.path" @click="pathItem(item)" v-if="!item.children">{{item.title}}</el-menu-item>
<el-sub-menu :index="item.title" style="width: 200px;" v-if="item.children">
<template #title>
<el-icon><icon-menu /></el-icon>
<span>{{item.title}}</span>
</template>
<el-menu-item-group v-for="itemc in item.children" :key="itemc">
<el-menu-item :index="itemc.path" @click="pathItem(itemc)">{{itemc.title}}</el-menu-item>
</el-menu-item-group>
</el-sub-menu>
</div>
</el-menu>
</template>
<script>
import {
Document,
Menu as IconMenu,
Location,
Setting,
} from '@element-plus/icons-vue'
import {reactive, ref} from 'vue'
import { useRouter } from 'vue-router'
export default {
components: { Document, Location, Setting, IconMenu },
setup() {
const $route = useRouter()
const menu = reactive([
{
path: '/home',
title: '首页',
children: [
{path: '/aa', title: 'aa'},
{path: '/bb', title: 'bb'},
{path: '/cc', title: 'cc'},
]
},
{
path: '/wei1',
title: 'wei1',
},
{
path: '',
title: '第二组',
children: [
{path: '/dd', title: 'dd'},
{path: '/ee', title: 'ee'},
{path: '/ff', title: 'ff'},
]
},
])
const nowPath = ref('/aa')
const handleOpen = function(key, keyPath){
console.log('key11',key)
console.log('keyPath11', keyPath)
console.log('keyPanowPath.valueth11', nowPath.value)
if(key == '首页' && nowPath.value === '/aa') {
console.log('2334')
$route.replace('/aa')
}
}
const handleClose = function(key, keyPath) {
console.log('key22',key)
console.log('keyPath22', keyPath)
}
const pathItem = item => {
nowPath.value = item.path
console.log('ddfsdf', nowPath.value)
}
return {handleOpen, handleClose, menu,pathItem, nowPath}
},
watch: {
$route(m, n) {
console.log('mm', m)
console.log('nn', n)
}
}
}
</script>
<style>
</style>
项目目录

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律