Vue / Router: Как правильно извлечь данные перед отображением содержимого страницы? - PullRequest
4 голосов
/ 14 февраля 2020

Я использую Nuxt с Vue Router и Ax ios. Я вижу, Vue Маршрутизатор имеет эту фантастическую c функцию, которая называется Навигационная защита .

К сожалению, в приведенном ниже примере вызывается моя функция beforeRouteEnter(), но, похоже, она выходит и переключает страницы до вызова моего ручного метода next() в fetchPageData(next).

Какой здесь правильный шаблон?

export default {
    beforeRouteEnter (to, from, next) {
        next(vm => {
            vm.fetchPageData(next);
        });
    },
    methods: {
        async fetchPageData(next) {
            const result = await this.$axios.$get('/api/v2/inventory/3906?apiKey=f54761e0-673e-4baf-86c1-0b85a6c8c118');
            this.$store.commit('property/setProperty', result[0]);
            next();
        }
    }
}

Я предполагаю, что мой первый вызов next(vm => {}) выполняется асинхронно, что позволяет продолжить выполнение, что приводит к изменению страницы до того, как я (большинство вероятно неправильно) попробуйте перезвонить далее ().

Ответы [ 2 ]

2 голосов
/ 14 февраля 2020

То, что там происходит, это то, что вы уже звоните next, и это , почему маршрут вводится немедленно.

Где вы Вы вызываете next?

beforeRouteEnter (to, from, next) {
    next(vm => {  // <= HERE you execute next
        vm.fetchPageData(next);
    });
},

И приведенный выше код будет выполняться vm.fetchPageData, когда компонент уже отрендерен.

Так что даже если вы не вызываете next на fetchPageData маршрут будет введен.


Предполагая, что вы хотите войти в представление после извлечения определенных данных BE, вы можете использовать beforeEnter в конфигурации маршрутизатора:

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        axios.get('api/...')
          .then(response => {
             store.commit('mutation', response)
             next()
          })
          .catch(e => {
            alert('Something went wrong')
            next(false)
          })
      }
    }
  ]
})

Другим решением было бы разрешить вход на маршрут, но при загрузке данных показывать загрузчик: Получить этот ответ

2 голосов
/ 14 февраля 2020

Вы правы, звоните next() второй раз неправильно. Ваш первый вызов next() сообщает Router: «go on, вы можете продолжить изменение активного компонента (создание / монтирование / рендеринг), а когда компонент будет создан, вызвать мой обратный вызов (передаваемый в качестве аргумента next())

Вы можете следовать указаниям в Выборка данных - выборка перед навигацией Документы ie. Выборка данных вначале и вызов next() после, но для этого требуется извлечь logi c из самого компонента .

Обычно мне проще написать все компоненты, если предположить, что данные отсутствуют при первом рендеринге и поступят позже, когда все вызовы asyn c разрешатся ...

ОБНОВЛЕНИЕ Nuxt asyn c параметры выборки данных

Поскольку вы используете Nuxt. js, у вас есть несколько других вариантов использования данных asyn c:

  1. nuxtServerInit - полезно для заполнения хранилища Vuex на стороне клиента данными со стороны сервера
  2. метод выборки - Метод выборки используется для заполнения хранилища перед отображением страницы. Это как * Метод 1026 *, за исключением того, что он не устанавливает данные компонента и позволяет поместить данные в хранилище. Возврат Promise из метода fetch заставит Nuxt ждать разрешения для разрешения, прежде чем он выполнит рендеринг компонента ...
  3. Метод asyncData может использоваться для извлечения данных и помещения их в компонент data. Возвращение Promise из метода asyncData заставит Nuxt ждать разрешения для разрешения обещания, прежде чем он выполнит рендеринг компонента ...
export default {
  async fetch({store, $axios}) {
    const result = await $axios.$get('/api/v2/inventory/3906');
    store.commit('property/setProperty', result[0]);
  }
}
...