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