suchen

Heim  >  Fragen und Antworten  >  Hauptteil

javascript - vue+vue-router+vuex+axios+elementUI verwendet die Hintergrundverwaltungsschnittstelle, um einen Fehler zu melden, wenn Sie nach der Aktualisierung auf das Menü klicken

Die Anforderung besteht darin, eine Backend-Verwaltungsschnittstelle mit zugehörigen Berechtigungsverwaltungsfunktionen zu erstellen. Die entsprechenden Ideen basieren auf dem Artikel „addRoutes implementiert Backend-Verwaltungsfunktionen“. Die spezifische Methode besteht darin, die Berechtigungen der Rolle im Backend zurückzugeben Durch Aufrufen der addRoutes-Methode beim dynamischen Laden verwaltet vuex den Routenladestatus und die geladenen Routen und speichert sie während des Festschreibungsvorgangs im SessionStorage. Unter normalen Umständen wird das Menü nach der Anmeldung normal angezeigt und die entsprechende Schnittstelle kann angeklickt werden. Nachdem die F5-Seite aktualisiert wurde, wird die Route aus sessionStorage entfernt und neu geladen. Das Menü kann zu diesem Zeitpunkt noch normal angezeigt werden, beim Klicken wird jedoch ein Fehler ausgegeben:

1

2

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

</code>

Ich bin ein Neuling, bitte helfen Sie mir herauszufinden, wo das Problem liegt

login.vue-Code-Snippet

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

<code>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>

store.js-bezogener Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

<code>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));

    }

 

}</code>

getters.js

1

2

3

4

5

6

<code>const menuitems = state => state.items

const isLoadRoutes = state => state.isLoadRoutes

export {

    menuitems,

    isLoadRoutes

}</code>

action.js

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<code>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)

}</code>

store.js

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<code>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

})</code>

main.js

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

<code>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')

</code>

Nachdem Sie sich zum ersten Mal angemeldet haben, klicken Sie wie gewohnt auf das linke Menü

Nach dem Aktualisieren mit F5 löst ein Klick auf das Menü einen Fehler aus

.]

Fehlercode

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

<code>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>

</code>

天蓬老师天蓬老师2842 Tage vor2640

Antworte allen(3)Ich werde antworten

  • 为情所困

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

    经过测试下来,发现发生这种问题的根本原因在于路由component参数在被json转换成字符串之后,然后转回对象的时候无法解析,我尝试了一下直接使用import Home from ‘xxx’ 来替代component的值之后便正常显示路由信息了。但是依然没从根本上解决该问题,头疼

    Antwort
    0
  • 三叔

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

    大概看了一下 我觉得你没必要把路由信息都存到sessionStorage中去的 只要存登录获取的信息就行了吧

    Antwort
    0
  • 某草草

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

    我觉得可以参考一下这篇文章/a/11...

    Antwort
    0
  • StornierenAntwort