【问题标题】:Reset Vue Value on Browser Back在浏览器返回上重置 Vue 值
【发布时间】:2021-12-01 05:11:43
【问题描述】:

背景

我们有一个结帐页面,一旦创建了订单对象,它就会重定向到 Stripe。因为这是通过 API 请求,所以需要一点时间。因此,我们需要在“结帐”按钮被点击后阻止它,这样它就不能被多次点击。

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

该应用在 Laravel 中与 Jetstream(w/ Inertia)一起使用,由于惯性,我们在表单成功时自己重置值方面受到限制。

问题

除非用户在重定向到 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 而不是数据方法,但同样的问题也适用。

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

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

【问题讨论】:

  • As this is via an API request it takes a little bit of time. 此 API 请求是否有完成处理程序?事务未完成是否会报错?
  • @jrend 完成后会将页面重定向到 Stripe,如果失败则抛出错误,然后 Inertia 会处理以显示。我可以看到没有完成处理程序正在工作,请参阅“尝试的解决方案”部分的第 2 段
  • 如果你把属性初始化放在mounted或者created钩子里面会有帮助吗? Mounted 将设置 this.loadingCheckout = false。即使客户点击返回,它也应该触发它。
  • @equi 我试过了,是的,但什么也没发生,即使控制台日志确实发生了,所以我知道它正在运行。我猜在生命周期中,Vue 的值设置发生在模块挂载之后

标签: javascript vue.js inertiajs jetstream


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    为了解决这个问题,我已经从使用 Inertia 表单方法 https://inertiajs.com/forms#submitting-forms 转而使用表单辅助方法 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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-31
      • 1970-01-01
      • 2015-07-18
      • 2022-01-21
      • 1970-01-01
      • 2016-04-23
      • 2010-10-24
      相关资源
      最近更新 更多