首页 > 解决方案 > Vue-router - 当用户点击菜单链接时如何取消操作

问题描述

不特定于 Vue.js,而是特定于 Javascript 单页应用程序。如果您有一个表单和一个运行时间相当长的提交操作,比如保存一些东西。提交操作应该保存一些内容,然后推送到新路由以获取成功消息。

在等待结果的同时,用户点击了另一个链接并离开了。

看到这个小提琴:

https://jsfiddle.net/hajbgt28/4/

const Home = { 
  template: '<div><button @click="submit">Save and go Bar!</button></div>',
  methods: {
     async submit() {
            await setTimeout(() => {
           this.$router.push("/bar");
        }, 5000);
     }
  }
};
const Foo = { template: '<div>Foo</div>' }
const Bar = { template: '<div>Bar</div>' }

const router = new VueRouter({
  mode: 'history',
  routes: [
    { path: '/', component: Home },
    { path: '/foo', component: Foo },
    { path: '/bar', component: Bar }
  ]
})

new Vue({
    router,
  el: '#app',
  data: {
    msg: 'Hello World'
  }
})
  1. 点击首页
  2. 点击按钮
  3. 立即点击“Foo”,您会看到“Foo”
  4. 等待几秒钟
  5. 页面更改为“栏”

我有两个解决方案:

这种情况的最佳做法是什么?

标签: javascriptvue.jssingle-page-applicationvue-router

解决方案


您可以使用beforeRouteLeave 导航守卫在切换路线时中止该操作(即,在您的示例中取消计时器)。

  1. 假设提交动作是可识别的,保存操作结果的ID(setTimeout在你的例子中保存定时器ID from 的返回值)。
  2. 向组件添加一个beforeRouteLeave处理程序以取消提交操作(即,在您的示例中清除计时器 ID)。
const Home = {
  methods: {
    submit() {
      this.timerId /* 1 */ = setTimeout(() => {
        this.$router.push("/bar");
      }, 5000);
    }
  },
  beforeRouteLeave (to, from, next) {
    clearTimeout(this.timerId) /* 2 */
    next()
  }
};

更新了 jsfiddle


推荐阅读