14

認証が必要な単一ページ アプリケーションがあります。ユーザーが認証されると、いくつかのページにアクセスするか、ブラウザーでリロード ボタンを押すと、認証データを提供する API が要求されます。次に、次のようなエラーが発生します。

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

このエラーは、API へのリクエストがまだ完了していないときに、 vue が認証データをレンダリングするために発生します。

vueが認証データをレンダリングする前に、最初に終了するまでvueにリクエストAPIを待機させることは可能ですか?

ここで何が起こっているのかをより明確にします。コードは次のとおりです。

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

3 に答える 3

14

あなたが言った問題は、存在しないオブジェクトにアクセスしようとすることです。エラーのため、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>

Vue 2.0 で非推奨になるため、v-if="!dataReady"代わりに使用しましたv-else

于 2016-06-09T19:54:47.597 に答える
2

次のように、Vue が object プロパティにアクセスしようとするのを防ぐことができます。

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

null場合によっては、Loading...メッセージを変更することもできます。

于 2016-06-10T02:19:53.167 に答える