如何在退出时停止 Vue.js 3 watch() API 触发

vol*_*one 6 vue.js vue-router vuejs3

我在 Vue 组件中实现了一个watch显示产品信息的组件。手表的watch对象为routevue-routerProductID。当它发生变化时,我想从后端API获取产品详细信息。

为了观看route,我这样做Product.vue

import { useRoute } from 'vue-router'

    export default {
      setup() {
        const route = useRoute();

        async function getProduct(ProductID) {
          await axios.get(`/api/product/${ProductID}`).then(..do something here)
        }
    
        // fetch the product information when params change
        watch(() => route.params.ProductID, async (newID, oldID) => {
            await getProduct(newId)
          },
          //watch options
          {
          deep: true,
          immediate: true
          }
        )
      },
    }
Run Code Online (Sandbox Code Playgroud)

上面的代码有效,但如果用户离开Product.vue,例如使用后退按钮返回主页,则会watch再次触发 并尝试使用undefinedProductID 调用 API(因为参数ProductID不存在)在主页上route)例如http://localhost:8080/api/product/undefined。这会导致应用程序中引发错误。

  1. 为什么watch当用户导航离开时会触发Product.vue
  2. 如何才能正确预防这种情况呢?我可以使用它来做到这一点if(newID) { await getProduct(newId) },但这似乎与watch应该做的事情违反直觉。

更新和解决方案 将以下内容放在顶部,替换您的路线的名称:

if (route.name !== "YourRouteName") {
   return;
}
Run Code Online (Sandbox Code Playgroud)

如果您不在您想要观看的路线上,这将确保不会发生任何事情。

pho*_*lly 1

我遇到了同样的问题。不监视当前路由,而是使用vue-router onBeforeRouteUpdate,它仅在路由更改且重复使用相同组件时才会被调用。

来自https://next.router.vuejs.org/guide/advanced/composition-api.html#navigation-guards

import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
import { ref } from 'vue'

export default {
  setup() {
    // same as beforeRouteLeave option with no access to `this`
    onBeforeRouteLeave((to, from) => {
      const answer = window.confirm(
        'Do you really want to leave? you have unsaved changes!'
      )
      // cancel the navigation and stay on the same page
      if (!answer) return false
    })

    const userData = ref()

    // same as beforeRouteUpdate option with no access to `this`
    onBeforeRouteUpdate(async (to, from) => {
      // only fetch the user if the id changed as maybe only the query or the hash changed
      if (to.params.id !== from.params.id) {
        userData.value = await fetchUser(to.params.id)
      }
    })
  },
}
Run Code Online (Sandbox Code Playgroud)