vue实现动态菜单之权限数据存储

vue中实现动态菜单功能数据存储问题


(刚接触前端不久,有问题请积极指正)

在vue.js中通过router.beforeEach(async(to, from, next) => {})方法来拦截路由实现动态菜单功能,这时候就需要一个存储介质来实现用户角色或者用户路由数据的存储.

最开始我针对动态菜单功能的解决方案是使用localStroage来存储用户对应的路由数组信息,但是在实际应用中出现了登录不同用户路由数据更新异常的bug.

在项目中中login的登录方法中调用获取路由数组的方法,登录方法的返回值中返回用户角色id,将用户角色id传入获取路由数组的方法中,获取用户路由数组,然后存储到localStroage中.

       this.$store.dispatch('user/login', this.loginForm).then(response => {
              if(response.errorCode=='0'){
                this.$store.dispatch('user/getMenu', {roleId:response.errorMsg}).then(response => {
                  //使用localStroage存储数据是永久的,会导致不同角色下路由不更新
                  //window.localStorage.setItem("routerMenu",JSON.stringify(response))
                  //在这里使用sessionStroage存储数据
                  sessionStorage.setItem("role",JSON.stringify(response))
                   })
                //登录成功跳转first首页
                // this.$router.push({
                //   path: this.redirect || '/first'
                // })
                this.$router.push({path:'/first'})
                this.loading = false
              }else{
                this.$message.error('用户名密码错误!')
                this.loading=false
              }
            })

当登录不同的用户时,由于localStroage中存储的数据时永久的,导致不同用户角色下路由不刷新.
因为刚开始对vue中的vuex不是很熟悉,又想到使vuex的state来存储用户路由数组信息,但是出现了F5刷新页面路由数据丢失的问题,原来vuex在F5页面刷新的时候,会进行初始化,导致存储的全局共享变量丢失的问题.

//这是store中的user.js中定义的变量
const getDefaultState = () => {
  return {
    token: getToken(),
    name: '',
    avatar: '',
    role:''
  }
}

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
  },
  SET_ROLE: (state,role)=>{
    state.role = role
  }
}
const actions = {
  login({ commit }, loginForm) {
    return new Promise((resolve, reject) => {
      login(loginForm).then(response => {
        if(response.errorCode=='0'){
          setToken('token-xxxxx')
          //使用vuex存储数据,页面刷新数据会消失.
          //将数据存储到vuex中
          //commit('SET_ROLE', response.errorMsg)
        }
         resolve(response)
      }).catch(error => {
        reject(error)
      })
    })
  },
}

后来想到使用sessionStroage来存储用户的路由信息,因为sessionStroage生命周期为当前窗口或标签页,一旦窗口或标签页被永久关闭了,那么所有通过它存储的数据也就被清空了。这个特性可以用来保证页面刷新数据不丢失的问题,同时解决了localStroage永久存储数据的问题.

最终的解决代码:

   if (hasGetUserInfo) {
        next()
      } else {
        try {
          await store.dispatch('user/getInfo')
          //vuex存储的数据在页面刷新时会消失,这里使用sessionStroage存储角色数据
          getRouter=JSON.parse(sessionStorage.getItem("role"))
          let getRouterMenu=filterAsyncRouter(getRouter,false,true)
          //404页面一定要在最后添加,否则会导致所有页面被拦截至404页面
          getRouterMenu.push({ path: '*', redirect: '/404', hidden: true })
          //在addRoutes之前要将路由对象push到路由数组中
          for(let item of getRouterMenu){
            router.options.routes.push(item)
          }
         router.addRoutes(getRouterMenu) // 动态添加可访问路由表
         next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
          //next()
        } catch (error) {
          //删除token
          await store.dispatch('user/resetToken')
          Message.error('Has Error')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }

注释:(这里引用度娘的数据)
localStroage和sessionStroage的区别:

localStorage和sessionStorage一样都是用来存储客户端临时信息的对象。

他们均只能存储字符串类型的对象(虽然规范中可以存储其他原生类型的对象,但是目前为止没有浏览器对其进行实现)。

localStorage生命周期是永久,这意味着除非用户显示在浏览器提供的UI上清除localStorage信息,否则这些信息将永远存在。

sessionStorage生命周期为当前窗口或标签页,一旦窗口或标签页被永久关闭了,那么所有通过sessionStorage存储的数据也就被清空了。

不同浏览器无法共享localStorage或sessionStorage中的信息。相同浏览器的不同页面间可以共享相同的 localStorage(页面属于相同域名和端口),但是不同页面或标签页间无法共享sessionStorage的信息。这里需要注意的是,页面及标 签页仅指顶级窗口,如果一个标签页包含多个iframe标签且他们属于同源页面,那么他们之间是可以共享sessionStorage的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue 2 中实现动态菜单权限控制可以通过以下步骤进行: 1. 创建菜单数据:首先,你需要创建一个菜单数据结构,包含菜单项的名称、路径和权限等信息。可以将菜单数据存储在一个数组或者从后端获取。 2. 创建权限指令:在 Vue 2 中,你可以通过自定义指令来实现权限控制。创建一个名为 `v-permission` 的指令,该指令接收一个权限值作为参数。 ```javascript // main.js Vue.directive('permission', { inserted: function(el, binding) { const permission = binding.value; // 获取传入的权限值 // 根据权限值判断是否显示该菜单项 if (!hasPermission(permission)) { el.parentNode && el.parentNode.removeChild(el); } } }); ``` 3. 在菜单组件中使用指令:在菜单组件中,使用 `v-permission` 指令来控制菜单项的显示与隐藏。将菜单项的权限值作为指令的参数传入。 ```html <template> <div> <router-link to="/home" v-permission="'home'">首页</router-link> <router-link to="/about" v-permission="'about'">关于</router-link> <!-- 其他菜单项 --> </div> </template> ``` 这样,只有具有相应权限的用户才能看到对应的菜单项。 4. 添加权限判断逻辑:在 `hasPermission` 函数中,根据用户的权限信息判断是否具有相应权限。 ```javascript function hasPermission(permission) { // 根据用户权限信息判断是否具有该权限 // 返回 true 或者 false } ``` 你可以根据具体的业务逻辑来实现 `hasPermission` 函数,例如从后端获取用户权限信息进行判断。 通过以上步骤,你可以在 Vue 2 中实现动态菜单权限控制。记得在菜单组件中使用 `v-permission` 指令,并在 `hasPermission` 函数中实现权限判断逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值