javascript - 组件内 Navigation Guard 回调不起作用 : Nuxt JS and `beforeRouteEnter`

标签 javascript vue.js vuejs2 vue-router nuxt.js

我有一个搜索表单和一个使用 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 or layouts/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/

相关文章:

javascript - 如何用vue.js取消预览图片和上传文件名

vue.js - 如何将我的 nuxt 通用应用程序转换为移动原生应用程序

javascript - 如何获取组件中的列表值?

javascript - 使用英特尔 XDK 进行 Web 和跨平台开发

javascript - dropzone js 上传文件卡在 100%

javascript - 在 vueJS 中导入 javascript 类

vue.js - Vue - 如何正确更改下拉文本?

javascript回调函数,变量映射

来自数组值的 Javascript 动态变量名称 (Appcelerator Titanium)

javascript - 以编程方式将控件添加到空数组时独立操作控件 - VueJS