Maison  >  Questions et réponses  >  le corps du texte

javascript - vue+vue-router+vuex+axios+elementUI utilise l'interface de gestion en arrière-plan pour signaler une erreur lorsque vous cliquez sur le menu après l'avoir actualisé

L'exigence est de créer une interface de gestion backend avec des fonctions associées de gestion des autorisations. Les idées pertinentes sont basées sur l'article "addRoutes implémente des fonctions de gestion backend". La méthode spécifique consiste à renvoyer les autorisations détenues par le rôle dans le backend lors de la journalisation. dans, en appelant la méthode addRoutes Chargement dynamique, vuex gère l'état de chargement des routes et les routes chargées, et les stocke dans sessionStorage pendant les opérations de validation. Dans des circonstances normales, après la connexion, le menu s'affiche normalement et l'interface correspondante peut être cliquée. Une fois la page F5 actualisée, la route est supprimée de sessionStorage et rechargée Data, le menu peut toujours être affiché normalement à ce moment, mais une erreur est générée lorsque vous cliquez :

.
vue.esm.js?65d7:431 [Vue warn]: Error in beforeCreate hook: "TypeError: Cannot read property 'call' of null"

Je suis un débutant, aidez-moi s'il vous plaît à découvrir quel est le problème

extrait de code login.vue

computed:{
      ...mapGetters([
          'menuitems',
          'isLoadRoutes'
          // ...
      ])
    },
    methods: {
      rememberPwd(){
        if(this.checked){
            localStorage.setItem('account',this.ruleForm2.account);
            localStorage.setItem('password',this.ruleForm2.checkPass );
        }
      },
      removePwd(){
        if(this.checked){
            localStorage.removeItem('account');
            localStorage.removeItem('password');
        }
      },
      handleReset2() {
        this.$refs.ruleForm2.resetFields();
        this.removePwd();
      },
      handleSubmit2(ev) {
        var _this = this;
        this.$refs.ruleForm2.validate((valid) => {
          if (valid) {
            //_this.$router.replace('/table');
            this.logining = true;
            //NProgress.start();
            var loginParams = { username: this.ruleForm2.account, password: this.ruleForm2.checkPass };
            requestLogin(loginParams).then(res => {
              this.logining = false;
              //NProgress.done();
              if (res.data.resultCode !== "SUCCESS") {
                this.$message({
                  message: res.data.resultDesc,
                  type: 'error'
                });
              } else {
                this.loginUser=res.data.userProfile;
                this.routes=res.data.routes;
                if(this.loginUser.doRemove){
                  this.removePwd();
                }else{
                  this.rememberPwd();
                }
                sessionStorage.setItem('user', JSON.stringify(res.data.userProfile));
                sessionStorage.setItem('security', JSON.stringify(this.routes));
                this.addMenu(this.routes);
                /*this.$router.push(this.routes);*/
                if (!this.isLoadRoutes) {
                  this.$router.addRoutes(this.routes);
                  for(let route of this.routes){
                      console.info(JSON.stringify(route));
                     this.$router.options.routes.push(route);
                  }
                  this.loadRoutes();
                }
                console.info('push to home')
                this.$router.push({ path: '/' });
              }
            });
          } else {
            console.log('error submit!!');
            return false;
          }
        });
      },
      ...mapActions([
         'addMenu',
         'loadRoutes'
      ])
    }
  

code associé store.js

import {ADD_MENU,LOAD_ROUTES,INIT_FROM_LS} from './mutations_type'

export const state = {
    items: [
    ],
    isLoadRoutes: false
}

export const mutations = {
    [ADD_MENU] (state, menuItems) {
        console.info('addmenu mutations');
        if (menuItems.length === 0) {
            state.items = []
        } else {
            state.items = menuItems;
            sessionStorage.setItem('state.items',JSON.stringify(state.items));
        }
    },
    [LOAD_ROUTES] (state) {
        state.isLoadRoutes = !state.isLoadRoutes;
        sessionStorage.setItem('state.isLoadRoutes',JSON.stringify(state.isLoadRoutes));
        console.info('change load routes states ' +state.isLoadRoutes);
    },
    [INIT_FROM_LS](state){
        if (sessionStorage.getItem('state.items')) {
            state.items = JSON.parse(localStorage.getItem('state.items'));
        }
        if (sessionStorage.getItem('state.isLoadRoutes')) {
            state.isLoadRoutes = JSON.parse(localStorage.getItem('state.isLoadRoutes'));
        }
        console.info('init from ls '+JSON.stringify(state));
    }

}

getters.js

const menuitems = state => state.items
const isLoadRoutes = state => state.isLoadRoutes
export {
    menuitems,
    isLoadRoutes
}

action.js

import {ADD_MENU,LOAD_ROUTES,INIT_FROM_LS} from './mutations_type'

export const addMenu = ({ commit }, menuItems) => {
    if (menuItems.length > 0) {
        commit(ADD_MENU, menuItems)
    }
}

export const loadRoutes = ({commit}) => {
    commit(LOAD_ROUTES)
}

export const initFromLs=({commit})=>{
    commit(INIT_FROM_LS)
}

store.js

import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
import {mutations,state} from './menu'
Vue.use(Vuex)


// 创建 store 实例
export default new Vuex.Store({
    state,
    actions,
    getters,
    mutations
})

main.js

import Vue from 'vue'
import App from './App'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-default/index.css'
import VueRouter from 'vue-router'
import store from './vuex/store'
import Vuex from 'vuex'
import 'font-awesome/css/font-awesome.min.css'

import {state} from  './vuex/menu'
import Login from './views/Login.vue'
import NotFound from './views/404.vue'
import Home from './views/Home.vue'

Vue.use(ElementUI)
Vue.use(VueRouter)
Vue.use(Vuex)

const router = new VueRouter({
    routes:[
            {
                path: '/login',
                component: Login,
                name: '',
                hidden: true
            },
            {
                path: '/404',
                component: NotFound,
                name: '',
                hidden: true
            },
            {
                path: '/',
                component: Home,
                hidden: true
            },
            ...generateRoutesFromMenu()
        ]
})

// Menu should have 2 levels.
function generateRoutesFromMenu (routes = []) {
    store.dispatch('initFromLs');
    for (let i = 0, l = state.items.length; i < l; i++) {
        let item = state.items[i]
        if (item.path) {
            routes.push(item);
        }
    }
    console.info('generate menu = '+state.items +' routes = '+routes);
    return routes
}

router.beforeEach((to, from, next) => {
  //NProgress.start();
  if (to.path == '/login') {
    sessionStorage.removeItem('user');
    sessionStorage.removeItem('security');
    sessionStorage.removeItem('state.items');
    sessionStorage.removeItem('state.isLoadRoutes');
  }
  let user = JSON.parse(sessionStorage.getItem('user'));
  if (!user && to.path != '/login') {
    next({ path: '/login' })
  } else {
    next();
  }
})


new Vue({
  store,
  router,
  render: h => h(App)
}).$mount('#app')

Après vous être connecté pour la première fois, cliquez sur le menu de gauche comme d'habitude

Après avoir actualisé avec F5, cliquer sur le menu génère une erreur

.]

Code d'erreur

vue.esm.js?65d7:520 TypeError: Cannot read property 'call' of null
    at callHook (eval at <anonymous> (app.js:770), <anonymous>:2533:20)
    at VueComponent.Vue._init (eval at <anonymous> (app.js:770), <anonymous>:3969:5)
    at new VueComponent (eval at <anonymous> (app.js:770), <anonymous>:4140:12)
    at createComponentInstanceForVnode (eval at <anonymous> (app.js:770), <anonymous>:3495:10)
    at init (eval at <anonymous> (app.js:770), <anonymous>:3329:45)
    at createComponent (eval at <anonymous> (app.js:770), <anonymous>:4871:9)
    at createElm (eval at <anonymous> (app.js:770), <anonymous>:4814:9)
    at VueComponent.patch [as __patch__] (eval at <anonymous> (app.js:770), <anonymous>:5309:9)
    at VueComponent.Vue._update (eval at <anonymous> (app.js:770), <anonymous>:2300:19)
    at VueComponent.updateComponent (eval at <anonymous> (app.js:770), <anonymous>:2416:10)
handleError @ vue.esm.js?65d7:520
callHook @ vue.esm.js?65d7:2534
Vue._init @ vue.esm.js?65d7:3968
VueComponent @ vue.esm.js?65d7:4139
createComponentInstanceForVnode @ vue.esm.js?65d7:3494
init @ vue.esm.js?65d7:3328
createComponent @ vue.esm.js?65d7:4870
createElm @ vue.esm.js?65d7:4813
patch @ vue.esm.js?65d7:5308
Vue._update @ vue.esm.js?65d7:2299
updateComponent @ vue.esm.js?65d7:2415
get @ vue.esm.js?65d7:2754
run @ vue.esm.js?65d7:2824
flushSchedulerQueue @ vue.esm.js?65d7:2591
(anonymous) @ vue.esm.js?65d7:652
nextTickHandler @ vue.esm.js?65d7:599
vue.esm.js?65d7:431 [Vue warn]: Failed to mount component: template or render function not defined.

found in

---> <Home> at C:\Users\Dio\git\vue-admin\src\views\Home.vue
       <App> at C:\Users\Dio\git\vue-admin\src\App.vue
         <Root>
天蓬老师天蓬老师2658 Il y a quelques jours2490

répondre à tous(3)je répondrai

  • 为情所困

    为情所困2017-06-12 09:32:35

    Après les tests, j'ai découvert que la cause première de ce problème est que le paramètre du composant de routage ne peut pas être analysé après avoir été converti en chaîne par json, puis reconverti en objet. J'ai essayé directement d'utiliser import Home from 'xxx' pour le remplacer. le composant. Après la valeur, les informations de routage seront affichées normalement. Mais le problème n’est toujours pas résolu sur le fond, c’est un casse-tête

    répondre
    0
  • 三叔

    三叔2017-06-12 09:32:35

    Après un examen grossier, je pense que vous n'avez pas besoin de sauvegarder toutes les informations de routage dans sessionStorage. Il vous suffit de sauvegarder les informations obtenues en vous connectant

    .

    répondre
    0
  • 某草草

    某草草2017-06-12 09:32:35

    Je pense que vous pouvez vous référer à cet article/a/11...

    répondre
    0
  • Annulerrépondre