在浏览器上重置 Vue 值

Reset Vue Value on Browser Back

背景

我们有一个结帐页面,一旦创建了订单对象,它就会重定向到 Stripe。由于这是通过 API 请求,因此需要一点时间。因此,我们需要在点击“结帐”按钮后将其屏蔽,以防止多次点击。

我们目前通过在单击按钮时显示加载图标来实现此目的,以实现我们切换变量值。

该应用程序 Laravel 带有 Jetstream(带惯性),由于惯性,我们在表单成功时自行重置值方面受到限制。

问题

这工作正常,除非用户在重定向到 Stripe 后单击浏览器后退按钮。如果他们这样做,加载图标保持可见,并且 Vue 似乎没有将变量的状态重置为 false。

示例代码

<template>
   <div>
      <div v-if="loadingCheckout">Loading</div>
      <button v-if="!loadingCheckout" @click="startPurchase">Checkout</button>
   </div>
</template>
<script>
   import { defineComponent, ref } from 'vue'
   export default defineComponent({
      data() {
        return {
            loadingCheckout: false,
        };
       },
       methods: {
        startPurchase() {
            this.loadingCheckout = true;
            // Create checkout logic
        }
       }
   })
</script>

尝试的解决方案

我们曾尝试使用 setUpbeforeMountmounted 等事件重置,但都没有成功。此外还尝试在设置内部使用 ref 而不是数据方法,但同样的问题也适用。

我们也尝试过使用一种方法来生成数据 属性 但同样的问题。还尝试在 onSuccess 等表单上使用 Inertia 回调,但是这些回调不会被触发,假设这是由于 JetStream 干扰造成的。

任何想法都会有所帮助,理想情况是我们可以只在页面的每次呈现期间应用此状态,而不会真正保存在内存中。我认为问题出在 Inertia/Vue 将状态存储在浏览器历史记录中。

您可以尝试使用 onpopstate 在您单击后退按钮时刷新页面。

window.onpopstate = function () {
  // reset your state
};

为了解决这个问题,我已经不再使用 Inertia 表单方法 https://inertiajs.com/forms#submitting-forms and instead used the form helper methods https://inertiajs.com/forms#form-helper,它确实有工作回调。

已更换

this.$inertia.post(route('purchase.store'));

this.$inertia.form().post(route('purchase.store'), {
    onFinish: () => this.loadingCheckout = false,
})

我的代码现在如下所示:

<template>
   <div>
      <div v-if="loadingCheckout">Loading</div>
      <button v-if="!loadingCheckout" @click="startPurchase">Checkout</button>
   </div>
</template>
<script>
   import { defineComponent, ref } from 'vue'
   export default defineComponent({
      data() {
        return {
            loadingCheckout: false,
        };
       },
       methods: {
        startPurchase() {
            this.loadingCheckout = true;
            // Create checkout logic
            
            this.$inertia.form().post(route('purchase.store'), {
                preserveScroll: true,
                onFinish: () => this.loadingCheckout = false,
            })
        }
       }
   })
</script>