因此,我正在尝试在main.js
文件中向axios发出请求。
如图所示,我正在使用vue-router在加载每个组件之前发出此请求。但是,当我的网页首次加载时,我无法使其正常工作。我的意思是,axios请求在组件加载后完成。然后,这将失败:
mounted() {
if (Vue.prototype.$user.role == "Owner") {
this.isOwner = true;
this.estancoId = Vue.prototype.$user.estanco;
}
},
它在控制台日志上显示此错误:
[Vue warn]: Error in mounted hook: "TypeError: Cannot read property 'role' of undefined"
found in
---> <Header> at src/components/Header.vue
<App> at src/App.vue
<Root>
我尝试通过异步/等待发出此请求,我尝试了方法mounted(), created(), beforeMount(), beforeCreate()
,但仍然相同。我是Vue.js的新手,我被困在这里,不知道该怎么办。
编辑整个文件以查看应用程序结构: main.js
import router from './router'
import Vue from 'vue'
import App from './App.vue'
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import axios from 'axios'
import Vuex from 'vuex'
// Install BootstrapVue
import 'leaflet/dist/leaflet.css';
Vue.use(BootstrapVue)
// Optionally install the BootstrapVue icon components plugin
Vue.use(IconsPlugin)
Vue.use(axios)
Vue.use(Vuex)
Vue.config.productionTip = false
const store = new Vuex.Store({
state: {
user : {}
},
mutations : {
set_user (state,user) {
state.user = user
}
}
})
export default store
/* eslint-disable */
router.beforeEach((to, from, next) => {
if (from.path.indexOf("modificarCatalogo") == -1 && to.path.indexOf("modificarCatalogo") == -1) {
localStorage.removeItem("catalogue");
}
if (localStorage.getItem("token") != null) {
axios
.get(`${process.env.VUE_APP_API_BASE_URL}/user/role`, {
headers: {
Authorization: "Token " + localStorage.getItem("token")
}
})
.then(response => {
store.commit('set_user', response.data);
console.log("First then")
console.log(store.state.user)
}).catch(function (error) {
// handle error case here
console.log(error);
}).then(function () {
// always executed
console.log("Second then")
next();
});
}else{
next();
}
});
/* eslint-enable */
Vue.use(router)
new Vue({
router,
render: h => h(App),
}).$mount('#app')
现在有了Vuex,因为我尝试了@ellisdod答案,但
App.vue
<template>
<div>
<Header />
<router-view />
<Footer />
</div>
</template>
然后,在 Header.vue 中,我在这里调用Vuex $ store,但这是相同的。我需要在所有地方都完成此操作,因此我尝试在App.vue中调用该方法,但仍然没有结果,它现在使用Vuex的解决方案返回一个空对象,但是只是一个空对象,而不包含用户数据。
export default {
name: "Header",
data() {
return {
token: localStorage.getItem("token"),
isOwner: "",
estancoId: ""
};
},
mounted() {
console.log("Header log")
if (this.$store.state.user.role == "Owner") {
this.isOwner = true;
this.estancoId = this.$store.state.user.estanco;
}
},
其余部分与我认为无关
答案 0 :(得分:0)
如果使用Vuex存储用户数据,则可以用空对象预填充用户值,这样它就不会引发错误。
const store = new Vuex.Store({
state: {
user : {}
},
mutations : {
set_user (state,user) {
state.user = user
}
},
actions : {
loadUserFromLocal ({commit,state}) {
if (localStorage.getItem("token") === null) return null
return axios
.get(`${process.env.VUE_APP_API_BASE_URL}/user/role`, {
headers: {
Authorization: "Token " + localStorage.getItem("token")
}
})
.then(response => {
commit('set_user', response.data);
console.log("First then")
console.log(state.user)
}).catch(function (error) {
// handle error case here
console.log(error);
})
}
}
})
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
然后在安装的主App组件的挂钩中添加:
mounted () {
this.$store.dispatch('loadUserFromLocal')
}
现在在您的路由器中,而不是在每条路由之前发出服务器请求,您只需检查商店即可:
if (this.$store.state.user.role) {
// handle logged in user
}
答案 1 :(得分:-1)
Vue-router的beforeEach方法将仅在路由中定义的组件中执行。
就您而言,
(100, 5)
。store.js
$user
@ellisdod-谢谢。
现在,您可以使用组件中存储的用户变量,并且在完成数据提取时将对其进行更新,或者将显示初始值直到该时间为止
因此无需在router.beforeEach中获取数据
router.js
import axios from 'axios'
import Vuex from 'vuex'
const store = new Vuex.Store({
state: {
user : {}
},
mutations : {
set_user (state,user) {
state.user = user
}
}
actions : {
loadUserFromLocal ({commit,state}) {
if (localStorage.getItem("token") === null) return null
return axios
.get(`${process.env.VUE_APP_API_BASE_URL}/user/role`, {
headers: {
Authorization: "Token " + localStorage.getItem("token")
}
})
.then(response => {
commit('set_user', response.data);
console.log("First then")
console.log(state.user)
}).catch(function (error) {
// handle error case here
console.log(error);
})
}
}
})
export default store
正如您在vue-router中所知道的,如果调用next,则认为导航已确认,并且组件将被渲染。
有关在 // --> all imports
import store from './store' // --> added
// --> all routes to be defined here...
router.beforeEach((to, from, next) => {
// --> other logic for filtering routes
// --> you can use 'store' variable here to get the user data and add
filtering
if (from.path.indexOf("modificarCatalogo") == -1 &&
to.path.indexOf("modificarCatalogo") == -1) {
localStorage.removeItem("catalogue");
}
next();
});
方法中使用store变量的更多信息,请参考this question
main.js
router.beforeEach
App.vue
import router from './router'
import store from './store' // --> added
import Vue from 'vue'
import App from './App.vue'
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
import axios from 'axios'
import Vuex from 'vuex'
// Install BootstrapVue
import 'leaflet/dist/leaflet.css';
Vue.use(BootstrapVue)
// Optionally install the BootstrapVue icon components plugin
Vue.use(IconsPlugin)
Vue.use(axios)
Vue.use(Vuex)
Vue.config.productionTip = false
Vue.use(router)
new Vue({
router,
store // --> added
render: h => h(App),
}).$mount('#app')
@ellisdod-谢谢。
Header.vue
mounted () {
this.$store.dispatch('loadUserFromLocal')
}