繁体   English   中英

VueJS 3:更新值并避免监视

[英]VueJS 3: update value and avoid watch

我正在编写一个带有分页组件的表格,我使用多个 v-model 并watch这些变量来获取数据。 perPage更新时,我想将page重置为 1。所以我在watch方法中这样做了,但是当然, watch被触发了两次(对于perPage ,然后是page )。

此时是否可以更新变量并禁用手表?

这是我当前的代码:


<script setup lang="ts">

const sort = ref(route.query.sort || 'created_at')
const filters = ref(route.query.filters || {})
const page = ref(route.query.page ? parseInt(route.query.page.toString()) : 1)
const perPage = ref(route.query.per_page ? parseInt(route.query.per_page.toString()) : 10)

watch([sort, filters, page, perPage], ([oldSort, oldFilters, oldPage, oldPerPage], [newSort, newFilters, newPage, newPerPage]) => {
  if (oldPerPage !== newPerPage)
    page.value = 1

  fetchItems()

  router.push({
    query: {
      ...route.query,
      sort: sort.value,
      // filters: filters.value,
      page: page.value,
      per_page: perPage.value,
    },
  })
})

async function fetchItems() {
  items.value = await userApi.list({
    filters: toRaw(filters.value),
    sort: sort.value,
    page: page.value,
    perPage: perPage.value,
  })
}
</script>

<template>
    <CTable
      :pagination-enabled="true"
      v-model:sort="sort"
      v-model:page="page"
      v-model:per-page="perPage"
      :total-items="items.meta.total"
      :total-pages="items.meta.last_page"
    />
</template>

我发现的唯一解决方法是在我重置page时返回:

watch(..., () => {
  if (oldPerPage !== newPerPage) {
    page.value = 1
    return
  }

  fetchItems()

  ...
})

它适用于我的情况,但对于其他一些情况,我想在不触发 watch 方法的情况下进行更新。

谢谢!

perPage创建另一个观察者:

watch([sort, filters, page, perPage], ([oldSort, oldFilters, oldPage, oldPerPage], [newSort, newFilters, newPage, newPerPage]) => {

  fetchItems()

  router.push({
    query: {
      ...route.query,
      sort: sort.value,
      // filters: filters.value,
      page: page.value,
      per_page: perPage.value,
    },
  })
})

watch(perPage, (newPerPage,oldPerPage ) => {
  if (oldPerPage !== newPerPage)
    page.value = 1
})

建议单独为单个属性创建监视以避免不必要的更新和冲突。 对于第一个手表,尝试用watchEffect替换它,因为您没有使用旧/新值:

watchEffect(() => {
  fetchItems()
  router.push({
    query: {
      ...route.query,
      sort: sort.value,
      // filters: filters.value,
      page: page.value,
      per_page: perPage.value,
    },
  })
})

考虑到 state 是通过v-model改变的,需要用 watcher 来观察。

为了避免观察者被多次触发,它应该实现问题中显示的附加条件,但是当page已经是1时它也需要不跳过更新,这不会导致额外的更新:

  if (oldPerPage !== newPerPage) {
    page.value = 1

    if (newPage !== 1)
      return
  }

否则,就像另一个答案所暗示的那样,需要有多个观察者。 如果导致异步副作用 ( fetchItems ) 的观察者不应被触发超过其需要的次数,并且除了perPage之外还有其他原因导致这种情况发生,则可以对其进行去抖动,例如:

watch(perPage, () => {
  page.value = 1
});

watch([sort, filters, page, perPage], debounce(() => {
  fetchItems()
  ...
}, 100));

感谢您的所有回答,我终于找到了使用VueUse - watchIgnorable的内容:

const { stop, ignoreUpdates } = watchIgnorable(page, (value) => {
  fetchItems()
})

watch(perPage, (newPerPage, oldPerPage) => {
  if (newPerPage !== oldPerPage) {
    ignoreUpdates(() => {
      page.value = 1
    })
  }

  fetchItems()
})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM