Reactive Arguments
Re-run a Convex query when filters, route parameters, or selected records change.
Query arguments can be a plain object, a ref, a computed value, or a getter. Nested refs are unwrapped before execution.
Filter a list
const search = ref('')
const includeArchived = ref(false)
const args = computed(() => ({
search: search.value.trim(),
includeArchived: includeArchived.value,
}))
const projects = useConvexQuery(api.projects.search, args, {
keepPreviousData: true,
})When either input changes, the composable requests the new argument set.
Keep the previous result deliberately
With keepPreviousData: true:
- The previous successful
dataremains visible for the same identity. pendingbecomes true for the new arguments.isStalebecomes true.- The new successful result replaces the previous value.
<template>
<ProjectList :projects="projects.data.value ?? []" :dimmed="projects.isStale.value" />
</template>The default is false, which clears the old result for an explicit loading transition. An identity generation change always clears old data, regardless of this option.
Skip incomplete arguments
Do not send placeholder IDs:
const args = computed(() => {
const id = route.params.projectId
return typeof id === 'string' ? { projectId: id } : 'skip'
})
const project = useConvexQuery(api.projects.get, args)Use only the literal 'skip'. null is valid Convex data, and undefined represents absent query data; neither is a public skip sentinel.
Auth-dependent execution
Prefer auth: 'required' over reading auth state only to skip a private query:
const projects = useConvexQuery(api.projects.mine, {}, { auth: 'required' })Use a computed 'skip' when another application condition also determines whether the query is meaningful.
Keep getters pure
Vue may evaluate a computed value more than once. Argument getters should only derive data. Do not navigate, mutate state, or perform network work inside them.