Компонент обратного вызова Navigation Guard не работает: Nuxt JS и `beforeRouteEnter` - PullRequest
4 голосов
/ 22 октября 2019

У меня есть форма поиска и страница с результатами поиска с Nuxt JS. Я пытаюсь перенаправить страницу результатов pages/results/index.vue обратно на страницу поиска pages/search/index.vue, если форма возвращает ошибки.

Я пытаюсь использовать In-Component Guards согласно документации Vue

Согласно документам:

Однако вы можете получить доступ к экземпляру, передав обратный вызов next. Обратный вызов будет вызван после подтверждения навигации, и экземпляр компонента будет передан обратному вызову в качестве аргумента:

beforeRouteEnter (to, from, next) {
  next(vm => {
    // access to component instance via `vm`
  })
}
// version info

├─┬ nuxt@2.10.1
│ ├─┬ @nuxt/builder@2.10.1
│ │ └─┬ @nuxt/vue-app@2.10.1
│ │   └── vue@2.6.10  deduped
│ └─┬ @nuxt/core@2.10.1
│   └─┬ @nuxt/vue-renderer@2.10.1
│     └── vue@2.6.10  deduped
└─┬ vue-glide-js@1.3.12
  └── vue@2.6.10

Моя главная проблема заключается в том, что обратный вызов в *Кажется, что функция 1017 * в защите навигации не работает для перенаправления страницы.

( со страницы )

// page/search/index.vue

<template>
  ...
  <nuxt-link to="/results" @click.native="doSearch">
    Show Results
  </nuxt-link>
  ...
</template>

<script>
export default {
  ...
  methods: {
    doSearch () {
      ... // validates search fields and adds content to store
    }
  },
  ...
}
</script>

Вышеописанное работает нормально,где doSearch проверяет форму и добавляет результаты (вместе с любыми ошибками) в хранилище.

Но затем в следующем ...

(от до page)

// pages/results/index.vue

<script>
export default {
  ...
  beforeRouteEnter (to, from, next) {
    next((vm) => {
      console.log(vm.validateRoute()) // works: '/search'
      vm.validateRoute()              // does not work: does nothing
    })
  },
  ...
  computed: {
    errors () {
      return this.$store.state.errors
    }
  },
  ...
  async fetch ({ store, params }) {
    await store.dispatch('searchresults/GET_RESULTS')
  },
  ...
  methods: {
    validateRoute () {
      let route = true
      if (this.errors.length > 0) {
        route = '/search'
      }
      console.log(this.erros.length)  // works: 7
      console.log(route)              // works: '/search'
      return route
    }
  },
  ...
}
</script>

Обратный вызов в beforeRouteEnter не оценивается и не вызывает изменения маршрута. Обратите внимание, что протоколирование показывает, что обратный вызов запускает и возвращает правильные значения.

Если я явно определяю маршрут без использования функции обратного вызова, он работает:

// pages/results/index.vue

<script>
export default {
  ...
  beforeRouteEnter (to, from, next) {
    next('/search')                   // works: re-routes to '/search' every time
  },
  ...
}
</script>

Я пыталсянесколько итераций next(callback) с ограниченным успехом ...

next(() => { return false })          // does not work
next(function () { return false })    // does not work

Но работают только явные объявления ...

next({ path: false })                 // works: prevents route change
next({ path: '/search' })             // works: changes route to '/search'

Я вполная потеря;это ошибка, или я что-то упустил?

Приложение

Ранее я пытался использовать промежуточное программное обеспечение, как указано в документации Nuxt здесь . Однако это привело к бесконечному циклу, как описано в этом сообщении в блоге .

// middleware/validate.js

export default function ({ store, redirect }) {
  console.log('middleware: validate')           // 'middleware: validate'
  if (store.state.errors.length > 0) {
    return redirect('/search')                  // ...endless loop
  }
  return true                                   // otherwise this works
}

// nuxt.config.js

export default {
  ...
  router: {
    middleware: "validate"
  },
  ...
}

Исправлено

Как указано @ ifaruki , размещение вызова промежуточного программного обеспечения внутри компонента страницы устраняет проблему бесконечного цикла:

Следующий шаг - добавление промежуточного программного обеспечения на страницу page / results / index.vue следующим образом:

export default {
   middleware: 'validate'
} 

Я нашел это в самом конце документов , который представляется методом Nuxt для Vue JS In-component Guards :

Вы также можете добавить свое промежуточное программное обеспечение к определенному макету или странице:

pages/index.vue или layouts/default.vue

: facepalm:

1 Ответ

1 голос
/ 23 октября 2019

В этом случае nuxt.js имеет свойство middleware.

Вы можете использовать middleware вместо охранников. В папке промежуточного программного обеспечения вы сначала создаете файл с именем, например, validate.js.

. В своем файле validate.js вы создаете функцию и помещаете туда свою логику проверки:

export default function ({ store, redirect }) {
  if (store.state.errors.length > 0) {
    return redirect('/search')
  }
}

СейчасВы установили свое промежуточное программное обеспечение. Следующим шагом будет добавление вашего промежуточного программного обеспечения на вашу страницу pages/results/index.vue следующим образом:

export default {
   middleware: 'validate'
} 

Промежуточное программное обеспечение всегда вызывается до создания экземпляра vue. Всякий раз, когда store.state.errors больше 0, вы будете перенаправлены обратно на /search, в противном случае это промежуточное ПО просто игнорируется.

Всегда сначала читайте документы nuxt, потому что nuxt не всегда ведет себя так же, как маршрутизатор vue.js или vue.js Официальные документы: https://nuxtjs.org/api/pages-middleware

...