Eager way to update query parameters #2359
-
What problem is this solvingI am having a hard time to describe the problem I am facing, but I try my best to make it clear. The following is just one example. Over the past years I had this issue multiple times and had a hard time finding issue and work around it. Imagine two composables (usePagination and useQueryFilters). Both update the query parameters of the current page. i.e.: router.replace({
name: route.name as RouteRecordName,
params: route.params,
query: {
...route.query,
page,
size: rowsPerPage,
},
}) There are situations where both do this at the same "tick". Component A is adding "paramA", Component B is adding "paramB". And while B tries to keep everything via Proposed solutionI wish I could update the query parameters in an eager way. If somewhere a router.push is being called I want to have access to the resulting route immediately. Maybe something like Describe alternatives you've consideredIt doesn't help to make an My current work-around is a "useQueryManager" composable which stores my changes internally and gives me an API to just update the query parameters and takes care of the syncing. It's really ugly and complicated, but works. Still, I would love to have a way to do this with vue-router nativly. let isInitialized = false
const queryState = ref({})
/**
* This state manager solves the problem that two `router.replace` calls (e.g. executed in a `watch` in separate `composables`)
* might overwrite each other, as the current state of `route.query` is only updated after the `router.replace` promise is fulfilled.
*/
export function useQueryManager() {
const router = useRouter()
const route = useRoute()
if (!isInitialized) {
Object.assign(queryState.value, route.query)
isInitialized = true
onBeforeUnmount(() => {
queryState.value = {}
isInitialized = false
})
watch(
() => route.query,
(newQuery) => {
Object.assign(queryState.value, newQuery)
},
{ immediate: true }
)
}
const updateQuery = (updates) => {
Object.keys(updates).forEach((key) => {
if (updates[key] === undefined || updates[key] === null || updates[key] === '') {
delete queryState.value[key]
} else {
queryState.value[key] = updates[key]
}
})
applyUpdates()
}
const applyUpdates = () => router.replace({ query: queryState.value })
watch(queryState, applyUpdates, { deep: true })
return { updateQuery }
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
use |
Beta Was this translation helpful? Give feedback.
The useRouteQuery composable from vueuse should allow that: it buffers changes to query so they are added up