当前位置: 首页 > news >正文

自存19-48

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

<template><button @click="dialogFormVisable = true ">打开</button><el-dialogv-model="dialogFormVisable":before-close="beforeClose"title="添加权限"width="500"><el-formref="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-treeref="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>

import 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-菜单管理添加接口联调

<template><button @click="dialogFormVisable = true ">打开</button><el-dialogv-model="dialogFormVisable":before-close="beforeClose"title="添加权限"width="500"><el-formref="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-treeref="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) returnawait 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>

import 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-菜单管理列表和编辑逻辑

<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-dialogv-model="dialogFormVisable":before-close="beforeClose"title="添加权限"width="500"><el-formref="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-treeref="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.datatableData.list = listtableData.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) returnawait 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-菜单管理剩余问题处理

<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-paginationv-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-dialogv-model="dialogFormVisable":before-close="beforeClose"title="添加权限"width="500"><el-formref="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-treeref="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 = valgetListData()}const handleCurrentChange = (val) => {paginationData.pageNum = valgetListData()}//请求列表数据const getListData = () =>{menuList(paginationData).then(({ data }) => {const { list, total } = data.datatableData.list = listtableData.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) returnawait 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>

<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>

import { 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-账号管理编辑分页功能完成

<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-paginationv-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-dialogv-model="dialogFormVisable":before-close="beforeClose"title="添加权限"width="500"><el-formref="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-selectv-model="form.permissions_id"placeholder="请选择菜单权限"style="width: 240px"><el-optionv-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.datalist.forEach(item => {item.create_time = dayjs(item.create_time).format('YYYY-MM-DD')})tableData.list = listtableData.total = total})
}const handleSizeChange = (val) => {paginationData.pageSize = valgetListData()
}
const handleCurrentChange = (val) => {paginationData.pageNum = valgetListData()
}//弹窗
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) returnawait formEl.validate((valid,fields) => {if(valid){const { name, permissions_id } = formupdateUser({ name, permissions_id}).then(({ data }) => {if( data.code === 10000 ){dialogFormVisable.value = falsegetListData()}})}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 = trueObject.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>

import 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-用户权限接口联调和动态路由数据组装

<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)//删除的非当前页tagif(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(//如果删除的是中间位置tagrouter.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>

<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 = 60countdown.validText = `获取验证码`flag = falseclearInterval(time)}else{countdown.time -= 1countdown.validText = `剩余${countdown.time}s`}},1000)flag = truegetCode({ 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>

const 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持久化实现

27-菜单高亮显示和用户信息显示问题解决

28-陪护管理新增陪护师弹窗

29-陪护新增表单校验和接口联调

30-陪护列表显示和接口联调

31-陪护师编辑和批量删除接口联调

32-【C端】项目创建引入router和vant UI

33-【C端】tabbar引入和layout组件实现

34-【C端】登录页面显示效果实现

35-【C端】axios二次封装和登录接口联调

36-【C端】首页页面效果实现

37-【C端】订单详情自定义头部和状态显示

38-【C端】订单详情选择医院功能

39-【C端】订单详情选择就诊时间功能

40-【C端】订单详情剩余表单显示

41-【C端】订单下单和支付功能实现

42-【C端】订单列表显示效果实现

43-【C端】订单详情显示效果(上)

44-【C端】订单详情显示效果(下)

45-【C端】我的页面显示效果

46-【C端】订单列表页面实现效果

47-【C端】订单列表服务状态扭转和问题解决

48-【完结】项目总结和回顾

http://www.dtcms.com/a/409873.html

相关文章:

  • ARM CoreSight:多核SoC调试追踪架构解析
  • Windows 显示器EDID笔记
  • 有哪些做任务的网站海淀区seo搜索引擎优化企业
  • 【C++实战㊻】解锁C++观察者模式:从理论到实战
  • 类和对象(二)
  • 开源多场景问答社区论坛Apache Answer本地部署并发布至公网使用
  • vue3 通过 Vue3DraggableResizable实现拖拽弹窗,可修改大小
  • 广州网站制作信科建设白名单 网站
  • DirBuster工具的文本介绍以及使用方法
  • DeepSeek-V3.1-Terminus:蓝耘API+CherryStudio实测国产最新开源模型,推理能力竟让我后背发凉
  • 金仓数据库:破解电子证照国产化难题,开启政务效能新篇
  • 杭州小蜜蜂网站建设宝坻做网站哪家好
  • 解析前端框架 Axios 的设计理念与源码:从 Promise 美学到双适配架构
  • MQTT 关键特性详解
  • 数据仓库与数据挖掘课程设计
  • 半导体数据分析:GPR算法小白入门(三) 晶体管I-V特性仿真教程
  • 深入理解 Qt 元对象系统:QMetaEnum 的应用与实践
  • html video标签mp4格式视频显示不出来的问题
  • Unity 虚拟仿真实验中设计模式的使用 ——策略模式(Strategy Pattern)
  • 企业级网站欣赏新乡个人网站建设
  • 设计模式——单例模式
  • C++设计模式之结构型模式:外观模式(Facade)
  • PaddleX服务化部署精度低于命令行调用的原因及解决方案
  • 新型域名前置攻击利用Google Meet、YouTube、Chrome及GCP构建流量隧道
  • 使用 C# 设置 Excel 单元格数据验证
  • python 做 网站移动互联网终端设备的主要技术指标是什么
  • Claude Code 的“AI优先”
  • 海外网站推广的公司app开发者需要更新
  • Unity-状态机复用
  • 沈阳铁西做网站公司成都移动网站建设