web-dev-qa-db-ja.com

beforeEnterフックで使用するためにvue-routerの非同期ストアデータにアクセスする方法は?

ストアアクションを介して非同期に取得されるbeforeEnterのストアデータにアクセスするにはどうすればよいですか?

import store from './vuex/store';

store.dispatch('initApp'); // in here, async data will be fetched and assigned to the store's state

// following is an excerpt of the routes object:
{
  path: '/example',
  component: Example,
  beforeEnter: (to, from, next) =>
  {
    if (store.state.asyncData) {
      // the above state is not available here, since it
      // it is resolved asynchronously in the store action
    }
  }
}

これは、最初のページのロード時またはページのリロード後、initデータがフェッチされ、ルーターがそのデータにユーザーがそのページにアクセスできるかどうかを待機する必要がある場合に特に重要です。

ルーターがデータの取得を「待機」することは可能ですか?または、非同期vuexストアデータと組み合わせてナビゲーションガードを処理する最良の方法は何ですか?

(beforeEnterフックはデフォルトのデータではなく、データベースからの実際のデータを決定する必要があるため、「asyncData」を事前に入力することは解決策にはなりません)

12
santacruz

here で説明されているように、vuexアクションからpromiseを返すことで実行でき、beforeEnter自体からディスパッチを呼び出します。

コードは次のようになります。

import store from './vuex/store';


// following is an excerpt of the routes object:
{
  path: '/example',
  component: Example,
  beforeEnter: (to, from, next) =>
  {
    store.dispatch('initApp').then(response => {
        // the above state is not available here, since it
        // it is resolved asynchronously in the store action
    }, error => {
        // handle error here
    })         
  }
}
13
Saurabh

初期値なしでstore.watch()を使用してこの問題を解決し、既に初期化されている場合は最新の値を返します。

ここに私のサンプルコードがあります

async function redirectIfNotAuth (to, from, next) {
  const user = await getUserState()
  if (user === null) {
    next({ name: 'auth' })
  } else {
    next()
  }
}

function getUserState () {
  return new Promise((resolve, reject) => {
    if (store.state.user === undefined) {
      const unwatch = store.watch(
        () => store.state.user,
        (value) => {
          unwatch()
          resolve(value)
        }
      )
    } else {
      resolve(store.state.user)
    }
  })
}


/* STORE */
const store = new Vuex.Store({
  state: {
    user: undefined
  }
})

/* ROUTER */
new Router({
  routes: [
    {
      path: '',
      name: 'home',
      component: Home,
      beforeEnter: redirectIfNotAuth
    },
    {
      path: '/signin',
      name: 'auth',
      component: Auth,
    }
  ]
})
5
Jeng Wittawat