2016-06-09 96 views
6

我有單個頁面應用程序需要驗證。當用戶通過身份驗證後,訪問一些頁面或點擊瀏覽器中的重新加載按鈕,它會請求提供auth數據的api。然後,我有這樣的錯誤:Vuejs在渲染數據之前同步請求

[Vue warn]: Error when evaluating expression "auth.name": TypeError: Cannot read property 'name' of null (found in component: <navbar>)

這個錯誤造成的,因爲VUE呈現權威性數據而到API請求還沒說完呢。

是否有可能使vue等待請求api,直到完成第一次vue渲染認證數據

更清楚地發生了什麼。下面是代碼:

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

你應該張貼您的代碼。我不認爲需要同步 –

+0

@YerkoPalma我正在使用vue-router和vuex。目前我把代碼(用於請求api)放在App.vue中ready() – antoniputra

+0

@YerkoPalma我的代碼就像一般的單頁應用程序項目,直到遇到此問題。 – antoniputra

回答

9

如你所說的問題是,您嘗試訪問的對象不存在,而且由於錯誤的,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

+0

此外,嘗試使用另一個循環鉤子而不是'ready',因爲DOM已經被渲染時調用ready,並且您希望在該事件之前使用該代碼。喜歡['created'](http://vuejs.org/guide/instance。html#Lifecycle-Diagram)hook –

+0

如果我在main.js中調用authService,那該怎麼辦?例如: '''auth.getUser(null,(response)=> { router.start(App,'#app') })''' 然後在App.vue中只使用以下方法接收auth數據:'' this.authData = auth.user' 我只是試試這個,像預期的那樣工作。但我不確定這是否是好解決方案 – antoniputra

+0

,因爲如果我使用您提供的解決方案。它會在每個routerComponent中有許多v-if =「dataReady」。 – antoniputra

2

你可以只阻止Vue公司的努力訪問對象屬性,像這樣:

{{ $root.authData ? $root.authData.name : null }} 

你甚至可以更改爲null在某些情況下Loading...消息。

1

你可以啓用該選項waitForData使用data transition hook

<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屬性加載檢查。

更多細節在這裏: http://router.vuejs.org/en/pipeline/data.html

+0

https://router.vuejs.org/en/pipeline/data.html現在是404 – chovy