Vue / Router:如何在呈现页面内容之前正确获取数据?

Spi*_*der 7 javascript vue.js vue-router nuxt.js

我将 Nuxt 与 Vue Router 和 Axios 一起使用。我看到 Vue Router 有一个很棒的功能,叫做Navigation Guards

不幸的是,在下面的示例中,我的beforeRouteEnter()函数被调用,但似乎在我的手动next()方法被调用之前退出并切换页面fetchPageData(next)

这里的正确模式是什么?

export default {
    beforeRouteEnter (to, from, next) {
        next(vm => {
            vm.fetchPageData(next);
        });
    },
    methods: {
        async fetchPageData(next) {
            const result = await this.$axios.$get('/api/v2/inventory/3906?apiKey=f54761e0-673e-4baf-86c1-0b85a6c8c118');
            this.$store.commit('property/setProperty', result[0]);
            next();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我假设我的第一次调用next(vm => {})是异步运行的,允许继续执行,从而在我(很可能是错误的)尝试回调 next() 之前导致页面更改。

rol*_*oli 6

那里发生的事情是,您已经呼叫next,这就是 路线立即进入的原因。

您接下来要打电话到哪里?

beforeRouteEnter (to, from, next) {
    next(vm => {  // <= HERE you execute next
        vm.fetchPageData(next);
    });
},
Run Code Online (Sandbox Code Playgroud)

vm.fetchPageData当组件已经渲染时,上面的代码将执行。

所以即使你不打电话,next路线fetchPageData也会进入。


假设您想在 BE 获取某些数据后进入视图,您可以beforeEnter在路由器配置上使用:

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        axios.get('api/...')
          .then(response => {
             store.commit('mutation', response)
             next()
          })
          .catch(e => {
            alert('Something went wrong')
            next(false)
          })
      }
    }
  ]
})
Run Code Online (Sandbox Code Playgroud)

另一个解决方案是允许路由进入,但在获取数据时显示加载程序:查看此答案


Mic*_*evý 5

你是对的,next()第二次打电话是不正确的。您的第一次调用next()告诉 Router“继续,您可以继续更改活动组件(创建/安装/渲染),并在创建组件时调用我的回调(作为参数传递给next()

您可以遵循数据获取 - 导航文档之前获取中的指导,即。首先获取数据,然后调用next(),但这需要从组件本身提取获取逻辑。

一般来说,我发现更容易以假设数据在第一次渲染时不在这里并且稍后在所有异步调用解析时出现的方式编写所有组件......

更新Nuxt 异步数据获取选项

当您使用 Nuxt.js 时,您还有一些其他选项来使用异步数据:

  1. nuxtServerInit - 用服务器端的数据填充客户端 Vuex 存储很有用
  2. fetch 方法- fetch 方法用于在渲染页面之前填充存储。它与该asyncData方法类似,只是它不设置组件数据并允许您将数据放入存储中。从方法返回 Promisefetch将使 Nuxt 在渲染组件之前等待 Promise 解析...
  3. asyncData方法可用于获取数据并将其放入组件的data. 从方法返回 PromiseasyncData将使 Nuxt 在渲染组件之前等待 Promise 解析...
export default {
  async fetch({store, $axios}) {
    const result = await $axios.$get('/api/v2/inventory/3906');
    store.commit('property/setProperty', result[0]);
  }
}
Run Code Online (Sandbox Code Playgroud)