vue2 项目实例 动态路由菜单(四)

news/2025/9/23 11:53:39/文章来源:https://www.cnblogs.com/congxueda/p/19105519

vue2 项目实例 动态路由菜单(四)

动态路由涉及到 router、 store、 beforeEach、 permission权限

 

1、触发登录事件

    Login.vue

监听路由变化,下次登录重定向上次页面

  watch: {$route: {handler: function(route) {this.redirect = route.query && route.query.redirect},immediate: true}},

 

登录按钮事件

handleLogin() {this.$refs.loginForm.validate((valid) => {if (valid) {this.loading = truethis.$store.dispatch('user/login', this.loginForm).then(() => {this.$router.push({ path: this.redirect || '/' })this.loading = false}).catch(() => {this.loading = false})} else {console.log('error submit!!')return false}})}

 

2、vuex

 store/module/user.js

import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter } from '@/router'const getDefaultState = () => {return {token: getToken(),name: '',avatar: ''}
}const state = getDefaultState()const mutations = {RESET_STATE: (state) => {Object.assign(state, getDefaultState())},SET_TOKEN: (state, token) => {state.token = token},SET_NAME: (state, name) => {state.name = name},SET_AVATAR: (state, avatar) => {state.avatar = avatar}
}const actions = {// user login
  login({ commit }, userInfo) {const { username, password } = userInforeturn new Promise((resolve, reject) => {login({ username: username.trim(), password: password }).then((response) => {console.log('login', response)const { data } = responsecommit('SET_TOKEN', data.token)setToken(data.token)resolve()}).catch((error) => {reject(error)})})},// get user info
  getInfo({ commit, state }) {return new Promise((resolve, reject) => {getInfo(state.token).then((response) => {const { data } = responseif (!data) {return reject('Verification failed, please Login again.')}const { name, avatar } = datacommit('SET_NAME', name)commit('SET_AVATAR', avatar)resolve(data)}).catch((error) => {reject(error)})})},// user logout
  logout({ commit, state }) {return new Promise((resolve, reject) => {logout(state.token).then(() => {removeToken() // must remove  token  first
          resetRouter()commit('RESET_STATE')resolve()}).catch((error) => {reject(error)})})},// remove token
  resetToken({ commit }) {return new Promise((resolve) => {removeToken() // must remove  token  firstcommit('RESET_STATE')resolve()})}
}export default {namespaced: true,state,mutations,actions
}

 

login 成功 resolve 执行路由跳转

 

3、路由守卫 permission

   

import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'NProgress.configure({ showSpinner: false }) // NProgress Configurationconst whiteList = ['/login'] // no redirect whitelist

router.beforeEach(async(to, from, next) => {// start progress bar
  NProgress.start()// set page titledocument.title = getPageTitle(to.meta.title)// determine whether the user has logged inconst hasToken = getToken()if (hasToken) {if (to.path === '/login') {// if is logged in, redirect to the home pagenext({ path: '/' })NProgress.done()} else {const hasGetUserInfo = store.getters.nameif (hasGetUserInfo) {next()} else {try {// get user infoawait store.dispatch('user/getInfo')
//获取路由列表,会触发 src/store/modules/permission.jsstore.dispatch(
'GenerateRoutes').then(accessRoutes => {// 根据roles权限生成可访问的路由表router.addRoutes(accessRoutes) // 动态添加可访问路由表next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 })next()} catch (error) {// remove token and go to login page to re-loginawait store.dispatch('user/resetToken')Message.error(error || 'Has Error')next(`/login?redirect=${to.path}`)NProgress.done()}}}} else {/* has no token*/if (whiteList.indexOf(to.path) !== -1) {// in the free login whitelist, go directly next()} else {// other pages that do not have permission to access are redirected to the login page.next(`/login?redirect=${to.path}`)NProgress.done()}} })router.afterEach(() => {// finish progress bar NProgress.done() })

 


src/store/modules/permission.js

4、请求路由接口

import {constantRoutes} from '@/router'
import {getRouters} from '@/api/menu' 
import Layout from '@/layout/index'const permission = {state: { routes: [], // 路由数据 
  },mutations: { SET_ROUTES: (state, routes) => {state.routes = constantRoutes.concat(routes)},SET_CURRENT_ROUTES: (state, routes) => {state.currentRoutes = routes}},actions: {// 生成路由
    GenerateRoutes({ commit }) {return new Promise(resolve => { // 向后端请求路由数据getRouters().then(res => {const accessedRoutes = filterAsyncRouter(res.data)accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes) // 找到代码 3标题处})})}} }
// 遍历后台传来的路由字符串,转换为组件对象 function filterAsyncRouter(asyncRouterMap) {
const res = []for(let i= 0; i < asyncRouterMap.length; i++ ){
// 组装路由模式 ⚠️
const temp = {...asyncRouteMap[i]}
if(asyncRouteMap[i].children){
temp.children = filterAsyncRouter(asyncRouteMap[i].children)
}else{
temp.component=loadView(temp.component)
}
res.push(temp)
}
return res }export const loadView = (view) => { // 路由懒加载return (resolve) => require([`@/views/${view}`], resolve) }export default permission

 

5、渲染左侧菜单

<template><div><el-menuclass="el-menu-vertical-demo":collapse="isCollapse"background-color="#545c64"text-color="#fff"active-text-color="#ffd04b"><h4>通用后台管理系统</h4>// 在子组件配置路由<AsideItems :menu="menu" /></el-menu></div>
</template><script>
import AsideItems from "./components/AsideItems";
export default {name: "CommonAside",components: {AsideItems,},data() {return {menu: [],};},mounted() {const mRoutes = this.$store.state.menu.menu;this.menu = mRoutes;},
};
</script>

 

 

<template><div><!-- 一定要加template遍历  递归调用 不然无效 --><template v-for="(item, i) in menu"><!-- 判断没有子路由的 --><el-menu-itemv-if="!item.children":key="i":index="item.name"@click="$router.push({ name: item.name })"><i :class="'el-icon-' + item.meta.icon"></i><span slot="title">{{ item.meta.title }}</span></el-menu-item><!-- 有子路由的导航 --><el-submenu v-else :key="i" :index="item.name"><template slot="title"><i :class="'el-icon-' + item.meta.icon"></i><span slot="title">{{ item.meta.title }}</span></template><!-- 子路由 --><aside-item :menu="item.children"></aside-item></el-submenu></template></div>
</template><script>
export default {name: "AsideItem",props: {menu: { type: Array },},
};
</script>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/912448.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

政务网站建设的三大核心功能是什么建设自己网站软件下载

一、简述静态网页和动态网页的区别。 静态网页: 静态网页是指运行于客户端的程序、网页、组件、纯粹HTML格式的网页; 如果有涉及网页内容的修改&#xff0c;就要修改源文件&#xff0c;重新上传到服务器。而且当网站信息量很大的时候&#xff0c;网页制作和维护都非常困…

重庆百度推广seo长春seo

很多同学不止一次和我反馈&#xff0c;我们的系统很混乱&#xff0c;主要表现在&#xff1a;应用的层次结构混乱&#xff1a;不知道应用应该如何分层、应该包含哪些组件、组件之间的关系是什么&#xff1b;缺少规范的指导和约束&#xff1a;新加一段业务逻辑不知道放在什么地方…

对于网站建设提出建议网站做APP麻烦吗

在计算机程序的开发过程中&#xff0c;随着程序代码越写越多&#xff0c;在一个文件里代码就会越来越长&#xff0c;越来越不容易维护。 为了编写可维护的代码&#xff0c;我们把很多函数分组&#xff0c;分别放到不同的文件里&#xff0c;这样&#xff0c;每个文件包含的代码…

网站后台链接怎么做平面设计手绘网站

原标题&#xff1a;个税起征点上调至5000&#xff0c;用Python算一算少交多少税今天出了一个重磅消息&#xff0c;个税起征点从3500上调到5000啦&#xff01; 广大IT农民工的生活压力又减轻了一些&#xff0c;有没有 晚上加一个鸡腿&#xff0c;要不要~ 开心归开心&#xff0c;…

气血不足做网站网站收索流量

不能过帐凭证:本币计的税基为0 消息编号 FF759 诊断 尝试步成本币中计税基数为零的凭证&#xff0c;尽管外币中税金额和计税基数不为零&#xff0c; 系统响应 拒绝凭证输入。 步骤 再次输入凭证。 这个错误的原因&#xff0c;是因为四舍五入导致的税为零。根据百度的反馈&…

网站开发公司名单网站托管团队

1 需求 我们需要实现携带时间头的一系列照片如下显示,现在我们拿到了图片集合,肯定需要对图片根据实现进行分组显示 date picture picture picture picture picture picture picture picture picturedate picture picture picture picture picture 2 代码实现 fun getImag…

网站建设需要哪些企业资料石家庄校园兼职网站建设

8月26日&#xff0c;2023未来产业发展大会在杭州未来科技城国际会议中心开幕&#xff01;会上&#xff0c;发布了未来科技城培育发展未来产业行动计划&#xff0c;启动了未来产业发展共同体&#xff0c;进行了未来产业公共服务平台签约仪式。未来科技城与加速科技签约共建集成电…

复古风格网站git做网站根目录

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;数据结构 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

app 微信 网站三合一企业宣传册模版

花了几天的时间&#xff0c;整出个 “hello spring boot”&#xff0c;并且把它从 2 搞到了 3。 纸上得来终觉浅&#xff01;自己实践出真知&#xff01;现在再回头来囫囵一遍&#xff0c;加深下印象。回想下从前自觉某一编程语言大都如此&#xff0c;先找到简单示例照着画一遍…

使用 feign 调用时对微服务实例进行选择

使用 feign 调用时对微服务实例进行选择1.概述 在 微服务 调用的时候,我们会需要将微服务实例进行分组的情况,我们有订单和库存服务,订单服务 和库存服务 分别 为 A,B两组服务实例。 A 服务分组服务A用户,B服务分组…

EI目录今年第3次更新!55本中国期刊被收录,附完整版下载

8月,EI Compendex数据库发布了最新版收录期刊目录。 目录实际更新时间为2025年7月24日 2025年截止8月份EI数据库已更新3次,更新时间分别为2025年1月、2025年4月和2025年7月。 本次目录共收录期刊5702本,其中包含Jou…

友点企业网站管理系统3d全屋定制设计软件

1.没镜像就拉取镜像 dockerhub中查看版本 官网 docker pull zookeeper:3.4.14 不加版本号也行&#xff0c;默认拉取最新版 创建并启动容器 docker run -p 2181:2181 --privilegedtrue --name zookeeper01 -d zookeeper –privilegedtrue 容器内用户开启root权限 docker ps…

程序员的未来:从技术岗位到全栈思维的进化之路 - 实践

程序员的未来:从技术岗位到全栈思维的进化之路 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&q…

envoy和nginx的区别

Envoy 和 Nginx 都是高性能的网络代理和反向代理服务器,广泛应用于现代分布式系统中。尽管它们在某些场景下功能重叠(如负载均衡、反向代理),但在设计目标、架构、功能特性和适用场景上存在显著差异。 以下是 Envo…

基于自适应差分进化算法的MATLAB实现

基于自适应差分进化算法(Adaptive Differential Evolution, ADE)的MATLAB实现一、算法原理 自适应差分进化算法通过动态调整缩放因子(F)和交叉概率(CR)提升全局搜索能力。核心改进包括:参数自适应:根据种群适应…

临沂专业网站建设公司哪家好做网站菜单背景图片

问你一句:「你知道 HTTP/1.1 该如何优化吗?」 我们可以从下面这三种优化思路来优化 HTTP/1.1 协议: 尽量避免发送 HTTP 请求在需要发送 HTTP 请求时&#xff0c;考虑如何减少请求次数减少服务器的 HTTP 响应的数据大小 下面&#xff0c;就针对这三种思路具体看看有哪些优化…

什么网站做推广效果好移动端网站没有icp

当遇到错误提示“vcruntime140.dll已加载&#xff0c;但找不到入口点”时&#xff0c;很多人可能会感到困惑&#xff0c;不知道如何去处理这个问题。不过没有必要紧张&#xff0c;在这里我会为大家详细解释 vcruntime140.dll 文件是什么&#xff0c;并指导大家如何高效地解决 v…

购物网站功能模块设计dw制作asp网站模板下载

题目&#xff1a; 给你一个下标从 0 开始的二维整数矩阵 grid&#xff0c;大小为 n * n &#xff0c;其中的值在 [1, n] 范围内。除了 a 出现两次&#xff0c;b 缺失 之外&#xff0c;每个整数都恰好出现一次 。 任务是找出重复的数字a 和缺失的数字 b 。 返回一个下标从 0 开始…

微网站平台微网站建设方案模板南昌企业网站建设公司

ETL服务内容包含&#xff1a; 数据迁移数据合并数据同步数据交换数据联邦数据仓库

电子商务网站建设课后习题答案成都服务器idc托管

文章目录 DFS排列组合问题排列组合问题的标准模板排列LeetCode46全排列题目描述代码 LeetCode47全排列Ⅱ题目描述代码 组合LeetCode77组合题目描述代码 LeetCode39组合总和题目描述代码 LeetCode40组合总和Ⅱ题目描述代码 LeetCode216组合总和Ⅲ题目描述代码 DFS排列组合问题 …