javascript - Vue.prototype 在页面首次加载时未定义
问题描述
所以,我试图在我的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>
我尝试使用 async/await 发出此请求,我尝试了方法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 的回答,但是
应用程序.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;
}
},
我认为其余的组件无关紧要
解决方案
如果你使用 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
}
推荐阅读
- python - 如何使用 Selenium 和 Python 查找与用户输入相关的元素?
- wordpress - WordPress:“全部”过滤器在管理员列表页面上不起作用?
- c++ - 如何声明已在静态库中定义的类?
- php - 具有数据库查询的多级循环
- python - 想要一个表现得像 ABC 但也是元类的类
- pyspark - PySpark / 计算出现次数并使用 UDF 创建新列
- reporting-services - SSRS 报告数据在下载为 pdf 时向上移动某些记录
- javascript - 如何使用 Jest 单元测试检查正在运行的函数中间的预期日志?
- postgresql - 如何知道函数的哪个参数是PostgreSQL表中的列?
- swift - AKAmplitudeTracker 幅度使用 audioKit 获得 0.0