19-菜单管理添加弹窗显示

javascript<template> <button @click="dialogFormVisable = true ">打开</button> <el-dialog v-model="dialogFormVisable" :before-close="beforeClose" title="添加权限" width="500" > <el-form ref="formRef" label-width="100px" label-position="left" :model="form" > <el-form-item label="名称" prop="name"> <el-input v-model="form.name" placeholder="请填写权限名称"/> </el-form-item> <el-form-item label="权限" prop="permissions"> <el-tree ref="treeRef" style="max-width: 600px;" :data="permissionData" node-key="id" show-checkbox :default-checked-keys="defaultKeys" /> </el-form-item> </el-form> </el-dialog> </template> <script setup> import { ref , reactive , onMounted } from 'vue' import { userGetMenu } from '../../../api' onMounted(() => { //菜单数据 userGetMenu().then(({ data })=>{ console.log(data) permissionData.value = data.data }) }) //form的数据 const form = reactive({ name:'', permissions:'' }) //树形菜单权限数据 const permissionData = ref([]) //弹窗的显示隐藏 const dialogFormVisable = ref(false) //关闭弹窗的回调 const beforeClose = () => { dialogFormVisable.value = false } //选中权限 const defaultKeys = [4,5] const treeRef = ref() </script> <style lang="less" scoped> </style>

javascriptimport request from '../utils/request' //发送验证码 export const getCode = (data) => { return request.post('/get/code',data) } //注册用户 export const userAuthentication = (data) =>{ return request.post('/user/authentication',data) } //登录 export const login = (data) =>{ return request.post('/login',data) } //权限管理列表 export const authAdmin = (params) => { return request.get('/auth/admin', { params }) } //菜单权限数据 export const userGetMenu = (params) => { return request.get('/user/getmenu', { params }) }
新添加的部分:

20-菜单管理添加接口联调
javascript<template> <button @click="dialogFormVisable = true ">打开</button> <el-dialog v-model="dialogFormVisable" :before-close="beforeClose" title="添加权限" width="500" > <el-form ref="formRef" label-width="100px" label-position="left" :model="form" :rules="rules" > <el-form-item v-show="false" prop="id"> <el-input v-model="form.id"/> </el-form-item> <el-form-item label="名称" prop="name"> <el-input v-model="form.name" placeholder="请填写权限名称"/> </el-form-item> <el-form-item label="权限" prop="permissions"> <el-tree ref="treeRef" style="max-width: 600px;" :data="permissionData" node-key="id" show-checkbox :default-checked-keys="defaultKeys" :default-expanded-keys="[2]" /> </el-form-item> </el-form> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="confirm(formRef)">确认</el-button> </div> </template> </el-dialog> </template> <script setup> import { ref, reactive, onMounted } from 'vue' import { userGetMenu, userSetMenu, menuList} from '../../../api' onMounted(() => { //菜单数据 userGetMenu().then(({ data })=>{ console.log(data) permissionData.value = data.data }) getListData() }) const paginationData = reactive({ pageNum: 1, pageSize: 10, }) //请求列表数据 const getListData = () =>{ menuList(paginationData).then(( data ) => { }) } const formRef = ref() //form的数据 const form = reactive({ id:'', name:'', permissions:'' }) //树形菜单权限数据 const permissionData = ref([]) //弹窗的显示隐藏 const dialogFormVisable = ref(false) //关闭弹窗的回调 const beforeClose = () => { dialogFormVisable.value = false } //选中权限 const defaultKeys = [4,5] const treeRef = ref() const rules = reactive({ name:[{ required: true, trigger:'blur',message:'请输入权限名称' }] }) //表单提交 const confirm = async(formEl) => { if (!formEl) return await formEl.validate((valid,fields) => { if(valid){ //获取到选择的checkbox数据 const permissions = JSON.stringify( treeRef.value.getCheckedKeys()) userSetMenu({ name: form.name, permissions, id: form.id}).then(({ data }) => { console.log(data) }) }else{ console.log('error submit!' , fields ) } }) } </script> <style lang="less" scoped> </style>

javascriptimport request from '../utils/request' //发送验证码 export const getCode = (data) => { return request.post('/get/code',data) } //注册用户 export const userAuthentication = (data) =>{ return request.post('/user/authentication',data) } //登录 export const login = (data) =>{ return request.post('/login',data) } //权限管理列表 export const authAdmin = (params) => { return request.get('/auth/admin', { params }) } //菜单权限数据 export const userGetMenu = (params) => { return request.get('/user/getmenu', { params }) } //菜单权限修改 export const userSetMenu = (data) => { return request.post('/user/setmenu',data) } //菜单权限列表 export const menuList = (params) => { return request.get('/menu/list', { params }) }

21-菜单管理列表和编辑逻辑

javascript<template> <button @click="open(null)">打开 </button> <el-table :data="tableData.list" style="width: 100%"> <el-table-column prop="id" label="id" /> <el-table-column prop="name" label="昵称" /> <el-table-column prop="permissionName" label="菜单权限" width="500px"/> <el-table-column label="操作"> <template #default="scope"> <el-button type="primary" @click="open(scope.row)">编辑</el-button> </template> </el-table-column> </el-table> <el-dialog v-model="dialogFormVisable" :before-close="beforeClose" title="添加权限" width="500" > <el-form ref="formRef" label-width="100px" label-position="left" :model="form" :rules="rules" > <el-form-item v-show="false" prop="id"> <el-input v-model="form.id"/> </el-form-item> <el-form-item label="名称" prop="name"> <el-input v-model="form.name" placeholder="请填写权限名称"/> </el-form-item> <el-form-item label="权限" prop="permissions"> <el-tree ref="treeRef" style="max-width: 600px;" :data="permissionData" node-key="id" show-checkbox :default-checked-keys="defaultKeys" :default-expanded-keys="[2]" /> </el-form-item> </el-form> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="confirm(formRef)">确认</el-button> </div> </template> </el-dialog> </template> <script setup> import { ref, reactive, onMounted, nextTick } from 'vue' import { userGetMenu, userSetMenu, menuList} from '../../../api' onMounted(() => { //菜单数据 userGetMenu().then(({ data })=>{ console.log(data) permissionData.value = data.data }) getListData() }) //列表数据 const tableData = reactive({ list: [], total: 0 }) //打开弹窗 const open = (rowData = {}) =>{ dialogFormVisable.value = true // 弹窗打开form生成是异步的 nextTick(() => { if(rowData){ Object.assign(form, { id:rowData.id , name: rowData.name }) treeRef.value.setCheckedKeys(rowData.permission) } }) } const paginationData = reactive({ pageNum: 1, pageSize: 10, }) //请求列表数据 const getListData = () =>{ menuList(paginationData).then(({ data }) => { const { list, total } = data.data tableData.list = list tableData.total = total }) } const formRef = ref() //form的数据 const form = reactive({ id:'', name:'', permissions:'' }) //树形菜单权限数据 const permissionData = ref([]) //弹窗的显示隐藏 const dialogFormVisable = ref(false) //关闭弹窗的回调 const beforeClose = () => { dialogFormVisable.value = false //重置表单 formRef.value.resetFields() //tree选择重置 treeRef.value.setCheckedKeys(defaultKeys) } //选中权限 const defaultKeys = [4,5] const treeRef = ref() const rules = reactive({ name:[{ required: true, trigger:'blur',message:'请输入权限名称' }] }) //表单提交 const confirm = async(formEl) => { if (!formEl) return await formEl.validate((valid,fields) => { if(valid){ //获取到选择的checkbox数据 const permissions = JSON.stringify( treeRef.value.getCheckedKeys()) userSetMenu({ name: form.name, permissions, id: form.id}).then(({ data }) => { console.log(data) }) }else{ console.log('error submit!' , fields ) } }) } </script> <style lang="less" scoped> </style>
22-菜单管理剩余问题处理

javascript<template> <panel-head/> <div class="btns"> <el-button :icon="Plus" type="primary" @click="open(null)" size="small">新增</el-button> </div> <el-table :data="tableData.list" style="width: 100%"> <el-table-column prop="id" label="id" /> <el-table-column prop="name" label="昵称" /> <el-table-column prop="permissionName" label="菜单权限" width="500px"/> <el-table-column label="操作"> <template #default="scope"> <el-button type="primary" @click="open(scope.row)">编辑</el-button> </template> </el-table-column> </el-table> <div class="pagination-info"> <el-pagination v-model:current-page="paginationData.pageNum" :page-size="paginationData.pageSize" :background="false" size="small" layout="total, prev, pager, next" :total="tableData.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </div> <el-dialog v-model="dialogFormVisable" :before-close="beforeClose" title="添加权限" width="500" > <el-form ref="formRef" label-width="100px" label-position="left" :model="form" :rules="rules" > <el-form-item v-show="false" prop="id"> <el-input v-model="form.id"/> </el-form-item> <el-form-item label="名称" prop="name"> <el-input v-model="form.name" placeholder="请填写权限名称"/> </el-form-item> <el-form-item label="权限" prop="permissions"> <el-tree ref="treeRef" style="max-width: 600px;" :data="permissionData" node-key="id" show-checkbox :default-checked-keys="defaultKeys" :default-expanded-keys="[2]" /> </el-form-item> </el-form> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="confirm(formRef)">确认</el-button> </div> </template> </el-dialog> </template> <script setup> import { ref, reactive, onMounted, nextTick } from 'vue' import { userGetMenu, userSetMenu, menuList} from '../../../api' import { Plus } from '@element-plus/icons-vue' onMounted(() => { //菜单数据 userGetMenu().then(({ data })=>{ console.log(data) permissionData.value = data.data }) getListData() }) //列表数据 const tableData = reactive({ list: [], total: 0 }) //打开弹窗 const open = (rowData = {}) =>{ dialogFormVisable.value = true // 弹窗打开form生成是异步的 nextTick(() => { if(rowData){ Object.assign(form, { id:rowData.id , name: rowData.name }) treeRef.value.setCheckedKeys(rowData.permission) } }) } const paginationData = reactive({ pageNum: 1, pageSize: 10, }) const handleSizeChange = (val) => { paginationData.pageSize = val getListData() } const handleCurrentChange = (val) => { paginationData.pageNum = val getListData() } //请求列表数据 const getListData = () =>{ menuList(paginationData).then(({ data }) => { const { list, total } = data.data tableData.list = list tableData.total = total }) } const formRef = ref() //form的数据 const form = reactive({ id:'', name:'', permissions:'' }) //树形菜单权限数据 const permissionData = ref([]) //弹窗的显示隐藏 const dialogFormVisable = ref(false) //关闭弹窗的回调 const beforeClose = () => { dialogFormVisable.value = false //重置表单 formRef.value.resetFields() //tree选择重置 treeRef.value.setCheckedKeys(defaultKeys) } //选中权限 const defaultKeys = [4,5] const treeRef = ref() const rules = reactive({ name:[{ required: true, trigger:'blur',message:'请输入权限名称' }] }) //表单提交 const confirm = async(formEl) => { if (!formEl) return await formEl.validate((valid,fields) => { if(valid){ //获取到选择的checkbox数据 const permissions = JSON.stringify( treeRef.value.getCheckedKeys()) userSetMenu({ name: form.name, permissions, id: form.id}).then(({ data }) => { beforeClose() getListData() }) }else{ console.log('error submit!' , fields ) } }) } </script> <style lang="less" scoped> .btns{ padding: 10px 0 10px 10px ; background-color: #fff; } </style>


javascript<template> <div class="panel-heading"> <div class="panel-lead"> <div class="title">菜单管理</div> <p class="description">菜单规则通常对应一个控制器的方法,同时菜单栏数据也从规则中获取</p> </div> </div> </template> <script setup> </script> <style lang="less" scoped> .panel-heading { padding: 15px; background: #e8edf0; border-color: #e8edf0; position: relative; .panel-lead { font-size: 14px; .title { font-weight: bold; font-style: normal; } .description { margin-top: 5px; } } } </style>


javascriptimport { createApp } from 'vue' import './style.css' import App from './App.vue' import router from './router' import store from './store' import PanelHead from './components/panelHead.vue' router.beforeEach((to,from) =>{ const token = localStorage.getItem('pz_token') //非登录页面token不存在 if (!token && to.path !== '/login') { return '/login' }else if (token && to.path === '/login'){ return '/' }else{ return true } }) // 如果您正在使用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) } app.component('PanelHead',PanelHead) //路由挂载 app.use(router) //store挂载 app.use(store) app.mount('#app')
23-账号管理列表




24-账号管理编辑分页功能完成

javascript<template> <panel-head/> <el-table :data="tableData.list" style="width: 100%"> <el-table-column prop="id" label="id" /> <el-table-column prop="name" label="昵称" /> <el-table-column prop="permissions_id" label="所属组别" > <template #default="scope"> {{ permissionName(scope.row.permissions_id) }} </template> </el-table-column> <el-table-column prop="mobile" label="手机号" /> <el-table-column prop="active" label="状态" > <template #default="scope"> <el-tag :type="scope.row.active ? 'success' : 'danger' ">{{ scope.row.active ? '正常' : '失效'}}</el-tag> </template> </el-table-column> <el-table-column label="创建时间" > <template #default="scope"> <div class="flex-box"> <el-icon><Clock /></el-icon> <span style="margin-left : 10px">{{ scope.row.create_time}}</span> </div> </template> </el-table-column> <el-table-column label="操作"> <template #default="scope"> <el-button type="primary" @click="open(scope.row)">编辑</el-button> </template> </el-table-column> </el-table> <div class="pagination-info"> <el-pagination v-model:current-page="paginationData.pageNum" :page-size="paginationData.pageSize" :background="false" size="small" layout="total, prev, pager, next" :total="tableData.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </div> <el-dialog v-model="dialogFormVisable" :before-close="beforeClose" title="添加权限" width="500" > <el-form ref="formRef" label-width="100px" label-position="left" :model="form" :rules="rules" > <el-form-item label="手机号" prop="mobile"> <el-input v-model="form.mobile" disabled/> </el-form-item> <el-form-item label="昵称" prop="name"> <el-input v-model="form.name" /> </el-form-item> <el-form-item label="菜单权限" prop="permissions_id"> <el-select v-model="form.permissions_id" placeholder="请选择菜单权限" style="width: 240px" > <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" /> </el-select> </el-form-item> </el-form> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="confirm(formRef)">确认</el-button> </div> </template> </el-dialog> </template> <script setup> import { authAdmin, menuSelectList, updateUser } from'../../../api' import { ref, reactive, onMounted } from 'vue' import dayjs from 'dayjs' const paginationData = reactive({ pageNum: 1, pageSize: 10, }) //列表数据 const tableData = reactive({ list: [], total: 0 }) onMounted(() => { getListData() menuSelectList().then(({ data }) => { options.value = data.data }) }) //请求列表 const getListData = () => { authAdmin(paginationData).then(({data}) => { console.log(data, 'authAdmin') const { list, total } = data.data list.forEach(item => { item.create_time = dayjs(item.create_time).format('YYYY-MM-DD') }) tableData.list = list tableData.total = total }) } const handleSizeChange = (val) => { paginationData.pageSize = val getListData() } const handleCurrentChange = (val) => { paginationData.pageNum = val getListData() } //弹窗 const dialogFormVisable = ref(false) const beforeClose = () => { } const rules = reactive({ name:[{ required: true, trigger: 'blur' , message:'请填写昵称' }], permissions_id:[{ required: true, trigger: 'blur' , message:'请选择菜单权限' }], }) //编辑表单 const formRef = ref() const form = reactive({ name:'', permissions_id:'', }) //表单提交 const confirm = async (formEl) => { if (!formEl) return await formEl.validate((valid,fields) => { if(valid){ const { name, permissions_id } = form updateUser({ name, permissions_id}).then(({ data }) => { if( data.code === 10000 ){ dialogFormVisable.value = false getListData() } }) }else{ console.log('error submit!' , fields ) } }) } const options = ref([]) //根据权限id匹配权限名称 const permissionName = (id) => { const data = options.value.find(el => el.id === id) return data ? data.name : '超级管理员' } const open = ( rowData ) => { dialogFormVisable.value = true Object.assign(form, { mobile:rowData.mobile, name: rowData.name, permissions_id:rowData.permissions_id }) } </script> <style lang="less" scoped> .flex-box{ display: flex; align-items: center; } </style>


javascriptimport request from '../utils/request' //发送验证码 export const getCode = (data) => { return request.post('/get/code',data) } //注册用户 export const userAuthentication = (data) =>{ return request.post('/user/authentication',data) } //登录 export const login = (data) =>{ return request.post('/login',data) } //权限管理列表 export const authAdmin = (params) => { return request.get('/auth/admin', { params }) } //菜单权限数据 export const userGetMenu = () => { return request.get('/user/getmenu') } //菜单权限修改 export const userSetMenu = (data) => { return request.post('/user/setmenu',data) } //菜单权限列表 export const menuList = (params) => { return request.get('/menu/list', { params }) } //权限下拉列表 export const menuSelectList = () =>{ return request.get('/menu/selectlist',) } //用户数据修改 export const updateUser = (data) => { return request.post('/update/user',data) }
25-用户权限接口联调和动态路由数据组装



javascript<template> <div class="header-container"> <div class="header-left flex-box" > <el-icon class="icon" size="20" @click="store.commit('collapseMenu')"><Fold /></el-icon> <ul class="flex-box"> <li v-for="(item,index) in selectMenu" :key="item.path" :class="{selected: route.path === item.path}" class="tab flex-box"> <el-icon size="12" ><component :is="item.icon" /></el-icon> <router-link class="text flex-box" :to="{ path:item.path }"> {{item.name}} </router-link> <el-icon size="12" class="close" @click="closeTab(item,index)"><Close /></el-icon> </li> </ul> </div> <div class="header-right"> <el-dropdown @command="handleClick"> <div class="el-dropdown-link flex-box"> <el-avatar src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"/> <p class="user-name">admin</p> </div> <template #dropdown> <el-dropdown-item command="cancel">退出</el-dropdown-item> </template> </el-dropdown> </div> </div> </template> <script setup> import { useStore } from 'vuex' import { computed } from 'vue' import { useRoute,useRouter } from 'vue-router' //拿到store的实例 const store = useStore() // 当前路由对象 const route = useRoute() const router = useRouter() const selectMenu = computed( ()=> store.state.menu.selectMenu) //点击关闭tag const closeTab = (item,index) =>{ store.commit('closeMenu',item) //删除的非当前页tag if(route.path !== item.path){ return } const selectMenuDate = selectMenu.value //删除的最后一项 if( index === selectMenuData.length){ //如果tag只有一个元素 if(!selectMenuData.length) { router.push('/') }else{ router.push({ path:selectMenuData[index -1].path }) } }else(//如果删除的是中间位置tag router.push({ path:selectMenuData[index].path }) ) } const handleClick = (command) => { if(command === "cancel" ){ localStorage.removeItem('pz_token') localStorage.removeItem('pz_userInfo') window.location.href = window.location.origin } } </script> <style lang="less" scoped> .flex-box{ display: flex; align-items: center; height: 100%; } .header-container { display: flex; justify-content: space-between; align-items: center; height: 100%; background-color: #fff; padding-right: 25px; .header-left{ height: 100%; .icon{ width: 45px; height: 100%; } .icon:hover{ background-color: #f5f5f5; cursor: pointer; } .tab{ padding: 0 10px; height: 100%; .text{ margin: 0 5px; } .close{ visibility: hidden; } &.selected{ a{ color: #409eff; } i{ color: #409eff; } background-color: #f5f5f5; } } .tab:hover{ background-color: #f5f5f5; .close{ visibility: inherit; cursor: pointer; color: #000; } } } .header-right{ .user-name{ margin-left: 10px; } } a{ height: 100%; color: #333; font-size: 15px; } } </style>




javascript<template> <el-row class="login-container" justify="center" :align="'middle'"> <el-card style="max-width: 480px"> <template #header> <div class="card-header"> <img :src="imgUrl" alt=""> </div> </template> <div class="jump-link"> <el-link type="primary" @click="handleChange">{{ formType ? '返回登录' : '注册账号' }}</el-link> </div> <el-form ref="loginFromRef" :model="loginForm" style="max-width: 600px" class="demo-ruleForm" :rules="rules" > <el-form-item prop="userName"> <el-input v-model="loginForm.userName" :prefix-icon="UserFilled" placeholder="手机号"></el-input> </el-form-item> <el-form-item prop="passWord"> <el-input v-model="loginForm.passWord" type="password" :prefix-icon="Lock" placeholder="密码"></el-input> </el-form-item> <el-form-item v-if="formType" prop="validCode"> <el-input v-model="loginForm.validCode" :prefix-icon="Lock" placeholder="验证码"> <template #append> <span @click="countdownChange">{{ countdown.validText }}</span> </template> </el-input> </el-form-item> <el-form-item> <el-button type="primary" :style="{width:'100%'}" @click="submitForm(loginFromRef)"> {{ formType ? '注册账号' : '登录'}} </el-button> </el-form-item> </el-form> </el-card> </el-row> </template> <script setup> import { ref, reactive, computed } from 'vue' import { getCode, userAuthentication, login, menuPermissions } from '../../api' import { UserFilled, Lock } from '@element-plus/icons-vue' import { useRouter } from 'vue-router' import { useStore } from 'vuex' const imgUrl = new URL('../../../public/login-head.png', import.meta.url).href //表单数据 const loginForm = reactive({ userName: '', passWord: '', validCode: '', }) //切换表单(0登录 1注册) const formType = ref(0) //点击切换登录和注册 const handleChange = () => { formType.value = formType.value ? 0 : 1 } //账号校验规则 const validateUser = (rule,value,callback) =>{ //不能为空 if(value === ''){ callback(new Error('请输入账号')) }else{ const phoneReg = /^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/ phoneReg.test(value) ? callback() : callback(Error('手机号格式不对,请输入正确手机号')) } } //密码校验 const validatePass = (rule,value,callback) =>{ //不能为空 if(value === ''){ calllback(new Error('请输入密码')) }else{ const reg = /^[a-zA-Z0-9_-]{4,16}$/ reg.test(value) ? callback() : callback(Error('密码格式不对,需要4-16位字符,请确认格式')) } } //表单校验 const rules = reactive({ userName : [{ validator: validateUser, trigger:'blur'}], passWord : [{ validator: validatePass, trigger:'blur'}] }) //发送短信 const countdown = reactive({ validText:'获取验证码', time:60 }) let flag = false const countdownChange = () =>{ //如果已发送不处理 if(flag) return //判断手机号是否正确 const phoneReg = /^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/ if (!loginForm.userName || !phoneReg.test(loginForm.userName)){ return ElMessage({ message: '请检查手机号是否正确', type: 'warning', }) } //倒计时 const time = setInterval(()=>{ if( countdown.time <= 0){ countdown.time = 60 countdown.validText = `获取验证码` flag = false clearInterval(time) }else{ countdown.time -= 1 countdown.validText = `剩余${countdown.time}s` } },1000) flag = true getCode({ tel: loginForm.userName}).then(({ data }) => { if(data.code === 10000){ ElMessage.success('发送成功') } }) } const router = useRouter() const loginFromRef = ref() const store = useStore() const routerList = computed(() => store.state.menu.routerList) //表单提交 const submitForm = async (formEl) => { if (!formEl) return //手动触发校验 await formEl.validate((valid, fields) => { if (valid) { //注册页面 if(formType.value){ userAuthentication(loginForm).then(({ data }) => { if (data.code === 10000) { ElMessage.success('注册成功,请登录') formType.value = 0 } }) }else{ //登录页面 login(loginForm).then(({data}) => { if (data.code === 10000) { ElMessage.success('登录成功!') console.log(data) //将token和用户信息缓存到浏览器 localStorage.setItem('pz_token', data.data.token) localStorage.setItem('pz_userInfo', JSON.stringify(data.data.userInfo)) menuPermissions().then(({ data }) => { store.commit('dynamicMenu', data.data) console.log(routerList, 'routerList') // router.push('/') }) } }) } } else { console.log('error submit!', fields) } }) } </script> <style lang="less" scoped> :deep(.el-card__header) { padding: 0 } .login-container { height: 100%; .card-header{ background-color: #899fe1; img { width: 430px; } } .jump-link { text-align: right; margin-bottom: 10px; } } </style>


javascriptconst state = { isCollapse : false, selectMenu: [], routerList: [] } const mutations = { collapseMenu(state){ state.isCollapse = !state.isCollapse }, addMenu(state,payload) { //对数据进行去重 if(state.selectMenu.findIndex(item => item.path === payload.path) === -1){ state.selectMenu.push(payload) } }, closeMenu(state,payload){ //找到点击数据的索引 const index = state.selectMenu.findIndex(val => val.name === payload.name ) //通过索引删除数组指定元素 state.selectMenu.splice(index,1) }, dynamicMenu( state, payload ) { //通过glob导入文件 const modules = import.meta.glob('../views/**/**/*.vue') console.log(modules) function routerSet(router){ router.forEach(route => { //判断没有子菜单,拼接路由数据 if ( !route.children ){ const url = `../views${route.meta.path}/index.vue` //拿到获取的vue组件 route.component = modules[url] }else{ routerSet(route.children) } }) } routerSet(payload) //拿到完整的路由数据 state.routerList = payload } } export default{ state, mutations }
26-动态路由添加和vuex持久化实现




















