Keperluan adalah untuk membina antara muka pengurusan bahagian belakang dengan fungsi pengurusan kebenaran yang berkaitan. Idea yang berkaitan adalah berdasarkan artikel "addRoutes melaksanakan fungsi pengurusan bahagian belakang". dalam, dengan memanggil kaedah addRoutes Pemuatan dinamik, vuex mengurus status pemuatan laluan dan laluan yang dimuatkan, dan menyimpannya dalam sessionStorage semasa operasi komit Dalam keadaan biasa, selepas log masuk, menu dipaparkan secara normal dan antara muka yang berkaitan boleh diklik. Selepas halaman F5 dimuat semula, laluan dikeluarkan dari sessionStorage dan dimuat semula Data, menu masih boleh dipaparkan seperti biasa pada masa ini, tetapi ralat dilemparkan apabila mengklik:
.vue.esm.js?65d7:431 [Vue warn]: Error in beforeCreate hook: "TypeError: Cannot read property 'call' of null"
Saya newbie, tolong bantu saya ketahui apa masalahnya
coretan kod log masuk.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'
])
}
store.js kod berkaitan
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')
Selepas log masuk buat kali pertama, klik pada menu kiri seperti biasa
Selepas menyegarkan dengan F5, klik pada menu menimbulkan ralat
.]
Kod ralat
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>
Selepas ujian, saya mendapati punca masalah ini ialah parameter komponen penghalaan tidak boleh dihuraikan selepas ditukar menjadi rentetan oleh json dan kemudian ditukar semula menjadi objek, saya cuba terus menggunakan import Home daripada 'xxx' untuk menggantikan komponen selepas nilai, maklumat penghalaan akan dipaparkan seperti biasa. Tetapi masalah itu masih belum diselesaikan secara asas, ia adalah sakit kepala
Setelah melihatnya secara kasar, saya rasa anda tidak perlu menyimpan semua maklumat penghalaan dalam sessionStorage Anda hanya perlu menyimpan maklumat yang diperoleh dengan log masuk
Saya rasa anda boleh rujuk artikel/a/11 ini...