我有一个搜索表单和一个使用 Nuxt JS 构建的结果页面。如果表单返回错误,我试图将结果页面 pages/results/index.vue
重定向回搜索页面 pages/search/index.vue
。
我正在尝试使用组件内保护 per the Vue documentation
根据文档:
However, you can access the instance by passing a callback to next. The callback will be called when the navigation is confirmed, and the component instance will be passed to the callback as the argument:
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
验证表单并将结果(连同任何错误)添加到商店。
但是接下来...
(到页面)
// 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 指出的那样,将中间件调用放在页面组件内修复了死循环问题:
Next step is to add your middleware to your page pages/results/index.vue like this:
export default { middleware: 'validate' }
我在 the docs 的最后找到了这个这似乎是 Vue JS In-component Guards 的 Nuxt 方法:
You can add your middleware to a specific layout or page as well:
pages/index.vue
orlayouts/default.vue
:脸掌:
最佳答案
对于这种情况,nuxt.js 有一个名为 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
关于javascript - 组件内 Navigation Guard 回调不起作用 : Nuxt JS and `beforeRouteEnter` ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58496743/