sourcecode

vue-router의 비동기 저장소 데이터에 액세스하여 beforeHook에서 사용하는 방법Enter hook?

copyscript 2022. 8. 19. 21:01
반응형

vue-router의 비동기 저장소 데이터에 액세스하여 beforeHook에서 사용하는 방법Enter hook?

스토어 액션을 통해 비동기적으로 검색된 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
    }
  }
}

이것은 첫 번째 페이지 로드 시 또는 페이지 새로고침 후에 특히 중요합니다.초기 데이터가 Import되어 라우터가 해당 데이터가 사용자가 해당 페이지에 액세스할 수 있는지 여부를 결정할 때까지 기다려야 합니다.

라우터가 데이터를 가져올 때까지 기다릴 수 있습니까?또는 비동기 vuex 저장소 데이터와 함께 내비게이션 가드를 처리하는 가장 좋은 방법은 무엇입니까?

(기본 데이터가 아닌 데이터베이스의 실제 데이터에 대해 beforeEnter 훅이 결정을 내려야 하므로 "asyncData"를 미리 입력하는 것은 해결책이 될 수 없습니다.)

vuex 액션에서 약속을 반환하면 됩니다.여기서 설명하는 바와 같이 디스패치를 호출하여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
    })         
  }
}

루트를 변경할 때마다 서버에서 데이터를 비동기적으로 가져올 필요가 있습니까?아니면 페이지가 새로고침되거나 사용자가 직접 링크를 사용할 때 데이터가 "소실되지 않도록" 저장소에서 데이터를 유지할 필요가 있습니까?

후자의 경우 인증 데이터(예: JWT 토큰)를 localStorage/cookie에 유지한 후 초기화 중에 스토리지에서 꺼낸 다음 저장하도록 커밋할 수 있습니다. 이는 동기 작업이어야 합니다.

vuex-perstisted state를 사용하여 저장소의 전체 상태를 유지할 수도 있으므로 새로고침 시 사라지지 않고 수분을 보충할 필요가 없습니다.

첫 번째 로드 또는 페이지 새로고침 전에 일부 데이터를 비동기적으로 한 번 가져와야 하는 경우 저장 작업을 디스패치하고 에서 Vue 인스턴스를 초기화할 수 있습니다.then()callback - 단, 구현에 따라 다를 수 있습니다.이런 느낌의 (in)main.js):

import Vue from 'vue';
import VueRouter from 'vue-router';
import { sync } from 'vuex-router-sync';

// contains VueRouter instance and route definitions
import router from 'src/router/router';
// contains Vuex.Store instance. I guess this is './vuex/store' in your example?
import store from 'src/store/store';

// sync the router with vuex store using vuex-router-sync
Vue.use(VueRouter);
sync(store, router);

// dispatch init action, doing asynchronous stuff, commiting to store
store.dispatch('initApp').then(() => {
    // create the main Vue instance and mount it
    new Vue({
        router,
        store           
    }).$mount('#app');
});

저는 이 문제를 상점을 통해 해결했습니다.초기값이 없는 경우 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,
    }
  ]
})

언급URL : https://stackoverflow.com/questions/42579601/how-to-access-async-store-data-in-vue-router-for-usage-in-beforeenter-hook

반응형