【问题标题】:How to update vue-router on page refresh?如何在页面刷新时更新 vue-router?
【发布时间】:2020-12-11 18:34:10
【问题描述】:

我有一个页面,其中包含一个路由器视图组件。我在父页面中还有一个按钮,当我单击它时,我会执行 router.push() 并通过参数将一些对象发送到命名路由。它工作得很好。但是,如果用户单击 F5 进行页面刷新,我显然无法再将必要的对象发送到我命名的路由,因为我无法捕获页面刷新。我已经对其进行了调试,并且命名的路由组件在我的父页面被挂载之前被挂载,并且似乎没有任何方法可以通知我的路由中的组件它需要来自父级的对象。是否不希望路由与父组件紧密耦合?谢谢。

   -- Parent component --

<button v-on:click="buttonClick">Get Tests</button>

<router-view></router-view>

...

    
const router = new VueRouter({
  mode: history,
  routes: [ 
    {
     path: "/school/:id/tests",
     name: "tests",
     component: testcomp,
     props: true
    }] 
});

new Vue ({
  router,
  methods: {
    buttonClick: function()
    {
      // ajax call to get tests

      // promise return
      .then( ret =>
      {
        router.push(
        {
          name: "tests",
          params: {
            allTests: ret.tests,
            id: 99,
          }
        });
      })
    },
  },
});

-- Child component --

...

props : {
  allTests: []
},

mounted: function()
{
  // fill in table with this.allTests
}

【问题讨论】:

  • 你是如何通过道具发送对象的?如果你能提供你所做的代码示例,那就太好了。
  • 我假设您的路线有 userId 参数,例如 users/:id ?由于路由可以刷新以根据具有相同用户 ID 的对象获取数据?并且 vue-router 启用了位置历史记录模式,所以我这方面的数据即使页面刷新也没有错。
  • @JonathanAkweteyOkine 我添加了一些简化代码

标签: vue.js vue-router


【解决方案1】:

从代码 sn-p 来看,我认为正在发生的事情是您正在发出 ajax 请求,并根据返回的承诺值在单击事件后将其作为参数传递。刷新页面不会调用 buttonClick 函数来获取参数。你应该做的是在RouteEnter前使用vue导航警卫来达到你的目的。您可以在创建组件之前使用此保护来获取您的数据。 如果可能的话,我会建议你重构你的代码。

 <router-link
  tag="button"
   :to="{
   name: 'tests',
   params: { id: 99},
   }"
 >

在子组件中,您可以使用 beforeRouteEnter 保护来发出您的 ajax 请求。请记住,这里不可用。

 async beforeRouteEnter(to, from, next) {
 const id= to.params.id;
 if (!id) {
  next("/404");
}
try {
  //example ajax resquest
 const response = await axios.get('/users/' + id)
  next((vm) => vm.setData(response));
} catch (error) {
  console.log(error);
  }
},

所以在这里,我们发出 ajax 请求,并通过调用 setData 方法在下一个回调中设置响应。

所以在我们的方法中,我们创建了 setData 函数。

methods: {
    setData(response){
     console.log(response)
     // here you have the response and access to this. so you can fill the table with the 
      data here
   }
}

你可以阅读更多关于 beforeRouteEnter 守卫here

【讨论】:

  • 谢谢。我研究了守卫,但我遇到的问题是父组件更多地充当子视图的控制器。会有很多类似的子视图,我希望父组件执行 ajax 调用,而不是依赖视图从警卫内执行。我想我更习惯 Angular 是如何做到这一点的。您选择了一条路线,但您仍然可以从在父组件中创建的路线定义中轻松地在子组件中设置道具。现在在页面刷新时,您无法设置子组件属性。
  • 我确实有一种在路线上使用 beforeEach 的组合方式。它会不断循环自己,直到 ajax 调用填充 vuex 存储。这样做不是一种干净的方式,但我可能不得不接受它。
【解决方案2】:

需要处理的方法是不要根据父级必须异步执行的操作推送路由。特定于子组件(路由中的那个)的数据需要负责它的查找。子组件应该只需要可以在 url 参数中处理的基本信息。如果我没记错的话,我来自 Angular 和 ng-router 模式,允许您在声明路由时将任何内容推送到路由中。路由是从父组件内部声明的,而不是像 vue 那样在其外部声明。无论如何,这就是我处理这个问题的方式。

【讨论】: