Vue element admin refreshes the page and jumps to the login page or 404 page Bug resolution record

Keywords: Javascript Vue.js debug

01 Bug description

The author carries out secondary development based on the simplified Vue element admin front-end framework Vue admin template.

I added the functions of authority authentication and dynamic routing in Vue admin template, that is, the front end generates dynamic routes according to different user roles and renders different pages.

After this function is added, the project will always refresh the page, jump directly to page 404, and then the system crashes, as shown in the figure:

02 trace Bug

Because I think it's the problem of permission authentication, I began to find the Bug here. The control code @ / permission.js of road level permission in the project is as follows:

import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getToken } from '@/utils/auth'
import getPageTitle from '@/utils/get-page-title'

NProgress.configure({ showSpinner: false })
const whiteList = ['/login']

router.beforeEach(async(to, from, next) => {
  NProgress.start()
  document.title = getPageTitle(to.meta.title)
  // Get user token
  const hasToken = getToken()
  // Login with token succeeded
  if (hasToken) {
  	// If you jump directly to the home page on the login page
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else {
      // If on other pages, judge whether the user has logged in
      const hasRoles = store.getters.roles && store.getters.roles.length > 0
      if (hasRoles) {
        next()
      } else {
      	// Get user role and generate dynamic route when logging in for the first time
        try {
          console.log('premission roles', store.getters.roles) // Used for debugging to check whether the user has successfully logged in
          await store.dispatch('user/getInfo')
          const accessRoutes = await store.dispatch('permission/generateRoutes', store.getters.roles)
          router.addRoutes(accessRoutes)
          next({ ...to, replace: true })
        } catch (error) {
          await store.dispatch('user/resetToken')
          Message.error(error || 'Has Error')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
  // Login failed, jump to login page
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})

The Debug statement console.log ('permission roles', store. Getters. Roles) in the above code is the key to finding bugs.

When logging in normally, the output of this statement is shown in the following figure. You can see that the user role is ROLE_ADMIN


When the 404 interface appears after refreshing the page, the user information output from the console can confirm that the user has successfully logged in, but the user role content output from the Debug statement is null

At this time, I think that user information, user roles and dynamic routing tables are stored in src/store/getters.js, as shown below:

const getters = {
  sidebar: state => state.app.sidebar,
  device: state => state.app.device,
  token: state => state.user.token,
  avatar: state => state.user.avatar,
  name: state => state.user.name,
  roles: state => state.user.roles,
  permission_routes: state => state.permission.routes
}
export default getters

So why does the user role information store.getters.roles disappear out of thin air?

At this time, I think of Vuex as a plug-in for state management, although it can solve the data sharing and data persistence between different components, and has higher data storage security; However, after refreshing the page, Vuex will update the state again, and the data stored in it will be lost, that is, the store will be reset.

03 resolving bugs

It has been found that in the vue project, when Vuex is used for status management, the data stored in the store will be reset after refreshing. How to solve this Bug?

One solution is to store the store in local localStorage, sessionStorage and cookie before refreshing the definition. They are applicable to different scenarios:

  • localStorage: permanent storage. The last opened page data will be read when the page is reopened
  • sessionStorage: save until closed
  • Cookies: not suitable for storing large amounts of data

Here, we use the compromise scheme sessionStorage to save the data before refresh locally. Modify the @ / App.vue file as follows to save the data locally

<template>
  <div id="app">
    <router-view />
  </div>
</template>

<script>
export default {
  name: 'App',
  created() {
    // Read the status information in sessionStorage when the page is loaded
    if (sessionStorage.getItem('store')) {
      this.$store.replaceState(
        Object.assign(
          {},
          this.$store.state,
          JSON.parse(sessionStorage.getItem('store'))
        )
      )
    }  

	// Save the information in vuex to sessionStorage when the page is refreshed
	// The beforeunload event is triggered first when the page is refreshed
    window.addEventListener('beforeunload', () => {
      sessionStorage.setItem('store', JSON.stringify(this.$store.state))
    })
  }
}
</script>

reference material

After the vue page is refreshed, the data in the store is cleared

Solve the problem of missing store data after vue refreshes the page

Posted by mattd8752 on Tue, 30 Nov 2021 01:45:31 -0800