我有单页面应用程序需要身份验证。当用户通过身份验证然后访问某些页面或点击浏览器中的重新加载按钮时,它将请求提供其身份验证数据的API。然后我有这样的错误:
[Vue warn]: Error when evaluating expression "auth.name": TypeError: Cannot read property 'name' of null (found in component: <navbar>)
导致此错误是因为当api请求尚未完成时,vue呈现身份验证数据。
是否可以让vue等待请求api直到完成,然后在vue渲染 auth数据之前?
更清楚地说明这里发生了什么。这是代码:
// main.js
import Vue from 'vue'
import App from './App.vue' // root vue
import store from './vuex/store' // vuex
import router from './router' // my router map
sync(store, router)
router.start(App, '#app')
// end main.js
// App.vue
<template>
<main>
<div class="wrapper">
<router-view></router-view>
</div>
</main>
</template>
<script>
import authService from './services/auth' // import authservice
ready () {
// here is code that should be done first before vue render all authData
auth.getUser((response) => {
self.authData = response
})
},
data () {
return {
authData: null // default is null until the api finish the process
}
}
</script>
// end App.vue
// SomeRouterComponents.vue
<template>
<!-- some content -->
<div>
// always got error: cannot read property 'name' of null
// here I expect to render this after api has been resolved
{{ $root.authData.name }}
</div>
<!-- some content -->
</template>
答案 0 :(得分:13)
您所说的问题是您尝试访问不存在的对象,并且由于该错误,Vue无法在下一个刻度中呈现它。解决方案是使用简单的v-if
来检查数据是否已加载,这仅适用于被动数据。
根组件
import auth from './services/auth' // import authservice
ready () {
// here is code that should be done first before vue render all authData
auth.getUser((response) => {
self.authData = response
self.dataReady = true
})
},
data () {
return {
authData: null, // default is null until the api finish the process
dataReady: false
}
}
<强> otherComponent 强>
<div v-if="dataReady">
// note that if you use v-show you will get the same error
{{ $root.authData.name }}
</div>
<div v-if="!dataReady">
// or some other loading effect
Loading...
</div>
我使用v-if="!dataReady"
代替v-else
,因为它将在Vue 2.0中弃用
答案 1 :(得分:2)
您可以阻止Vue尝试访问对象属性,如下所示:
{{ $root.authData ? $root.authData.name : null }}
在某些情况下,您甚至可以为null
消息更改Loading...
。
答案 2 :(得分:2)
您可以使用启用了data transition hook
选项的waitForData
:
<script>
import authService from './services/auth'
export default {
route: {
waitForData: true, // wait until data is loaded
data (transition) {
authService.getUser((response) => {
transition.next({ authData: response }) // set data
})
}
},
data () {
return {
authData: null
}
}
}
</script>
此外,如果您不想使用该选项,则可以使用$loadingRouteData
属性检查数据是否已加载。