我有一个搜索表单,并使用Nuxt JS构建了结果页面。如果表单返回错误,我试图将结果页面pages/results/index.vue
重定向回搜索页面pages/search/index.vue
。
我正在尝试使用组件内防护per the Vue documentation
根据文档:
但是,您可以通过将回调传递给next来访问实例。确认导航后,将调用该回调,并将组件实例作为参数传递给回调:
beforeRouteEnter (to, from, next) { next(vm => { // access to component instance via `vm` }) }
// version info
├─┬ [email protected]
│ ├─┬ @nuxt/[email protected]
│ │ └─┬ @nuxt/[email protected]
│ │ └── [email protected] deduped
│ └─┬ @nuxt/[email protected]
│ └─┬ @nuxt/[email protected]
│ └── [email protected] deduped
└─┬ [email protected]
└── [email protected]
我的主要问题是导航卫士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
验证表单并将结果(以及所有错误)添加到商店中。
但是随后在下面...
(<< [to页面)
// 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 documentation here中提到的中间件。但是,这导致了无限循环,如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" }, ... }
固定
@ifaruki指出,将中间件调用放在页面组件内部可解决无休止的循环问题:下一步是将中间件添加到页面pages / results / index.vue,如下所示:
export default { middleware: 'validate' }
我在the docs的末尾发现了这一点,这似乎是Vue JS In-component Guards的Nuxt方法:您也可以将中间件添加到特定的布局或页面:[
pages/index.vue
或layouts/default.vue
:facepalm:
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