组件内Navigation Guard回调不起作用:Nuxt JS和\`beforeRouteEnter\`

JavaScript Vue.js

泡芙

2020-03-24

我有一个搜索表单,并使用Nuxt JS构建了结果页面。如果表单返回错误,我试图将结果页面重定向pages/results/index.vue回搜索页面pages/search/index.vue

我正在尝试根据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

我的主要问题是next()导航卫士中的函数回调似乎无法重新路由页面。

来自页面)

// 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验证表单并将结果(以及所有错误)添加到商店中。

但是接下来...

(the to 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>

The callback in beforeRouteEnter does not appear to be evaluated and does not cause the route to change. Note the logging shows the callback is firing and returning the proper value(s).

If I explicitly define the route, without using a callback function, it works:

// pages/results/index.vue

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

I tried several iterations of the next(callback) with limited success...

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

But only explicit declarations work...

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

I'm at a total loss; is this a bug, or am I missing something?

Addendum

I previously tried using middleware as mentioned in the Nuxt documentation here. However this resulted in an endless loop, as discussed in this blog post.

// 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"
  },
  ...
}

Fixed

正如@ifaruki指出的那样,将中间件调用放在页面组件内部可解决无休止的循环问题:

下一步是将中间件添加到页面pages / results / index.vue中,如下所示:

export default {
   middleware: 'validate'
} 

在文档的结尾发现了这一点,它似乎是Vue JS组件内防护的Nuxt方法

您也可以将中间件添加到特定的布局或页面:

pages/index.vue 要么 layouts/default.vue

:facepalm:

第3493篇《组件内Navigation Guard回调不起作用:Nuxt JS和\`beforeRouteEnter\`》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

0个回答

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android