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格式的网页; 如果有涉及网页内容的修改,就要修改源文件,重新上传到服务器。而且当网站信息量很大的时候,网页制作和维护都非常困…
重庆百度推广seo长春seo
很多同学不止一次和我反馈,我们的系统很混乱,主要表现在:应用的层次结构混乱:不知道应用应该如何分层、应该包含哪些组件、组件之间的关系是什么;缺少规范的指导和约束:新加一段业务逻辑不知道放在什么地方…
对于网站建设提出建议网站做APP麻烦吗
在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。
为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码…
网站后台链接怎么做平面设计手绘网站
原标题:个税起征点上调至5000,用Python算一算少交多少税今天出了一个重磅消息,个税起征点从3500上调到5000啦!
广大IT农民工的生活压力又减轻了一些,有没有
晚上加一个鸡腿,要不要~
开心归开心,…
气血不足做网站网站收索流量
不能过帐凭证:本币计的税基为0 消息编号 FF759 诊断 尝试步成本币中计税基数为零的凭证,尽管外币中税金额和计税基数不为零, 系统响应 拒绝凭证输入。 步骤 再次输入凭证。
这个错误的原因,是因为四舍五入导致的税为零。根据百度的反馈&…
网站开发公司名单网站托管团队
1 需求
我们需要实现携带时间头的一系列照片如下显示,现在我们拿到了图片集合,肯定需要对图片根据实现进行分组显示
date
picture picture picture
picture picture picture
picture picture picturedate
picture picture picture
picture picture 2 代码实现 fun getImag…
网站建设需要哪些企业资料石家庄校园兼职网站建设
8月26日,2023未来产业发展大会在杭州未来科技城国际会议中心开幕!会上,发布了未来科技城培育发展未来产业行动计划,启动了未来产业发展共同体,进行了未来产业公共服务平台签约仪式。未来科技城与加速科技签约共建集成电…
复古风格网站git做网站根目录
🎈个人主页:豌豆射手^ 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:数据结构 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进…
app 微信 网站三合一企业宣传册模版
花了几天的时间,整出个 “hello spring boot”,并且把它从 2 搞到了 3。 纸上得来终觉浅!自己实践出真知!现在再回头来囫囵一遍,加深下印象。回想下从前自觉某一编程语言大都如此,先找到简单示例照着画一遍…
使用 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 不加版本号也行,默认拉取最新版 创建并启动容器
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 请求时,考虑如何减少请求次数减少服务器的 HTTP 响应的数据大小
下面,就针对这三种思路具体看看有哪些优化…
什么网站做推广效果好移动端网站没有icp
当遇到错误提示“vcruntime140.dll已加载,但找不到入口点”时,很多人可能会感到困惑,不知道如何去处理这个问题。不过没有必要紧张,在这里我会为大家详细解释 vcruntime140.dll 文件是什么,并指导大家如何高效地解决 v…
购物网站功能模块设计dw制作asp网站模板下载
题目: 给你一个下标从 0 开始的二维整数矩阵 grid,大小为 n * n ,其中的值在 [1, n] 范围内。除了 a 出现两次,b 缺失 之外,每个整数都恰好出现一次 。 任务是找出重复的数字a 和缺失的数字 b 。 返回一个下标从 0 开始…
电子商务网站建设课后习题答案成都服务器idc托管
文章目录 DFS排列组合问题排列组合问题的标准模板排列LeetCode46全排列题目描述代码 LeetCode47全排列Ⅱ题目描述代码 组合LeetCode77组合题目描述代码 LeetCode39组合总和题目描述代码 LeetCode40组合总和Ⅱ题目描述代码 LeetCode216组合总和Ⅲ题目描述代码 DFS排列组合问题
…