[英]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.