Validate matching Vue passwords: computed property or watcher?
Whether you derive state or watch imperatively.
Use a computed boolean for caching and dependency tracking; reserve watchers for side effects only.
Using a watcher to sync a match flag, wasting cycles and causing bugs.
WHAT THIS TESTS: This question probes your mental model of Vue reactivity and whether you can distinguish derived state from side effects. The interviewer wants to see if you understand that computed properties are for declarative transformations of reactive data, while watchers are for imperative reactions to changes. They also care if you know that computed properties cache results and only re-evaluate when dependencies change, which is critical for form validation performance and clean component architecture.
A GOOD ANSWER COVERS: First, recommend a computed property that returns a boolean or an error string based on whether the password equals the confirmPassword value. Explain that computed properties are cached and only re-run when either password field changes, making them efficient for direct template binding. Second, state that a computed property keeps the validation logic declarative and co-located with the data it depends on, which simplifies debugging and unit testing. Third, clarify that watchers should be reserved for side effects such as triggering an async API call to check password strength, logging analytics, or updating external non-reactive state, not for deriving UI state that can be expressed as a function of existing refs. Fourth, mention that using a computed property avoids creating a secondary source of truth because the template reads directly from the derived value instead of a manually synced data property that can drift.
COMMON WRONG ANSWERS: A red flag is suggesting a watcher that sets a data property like isMatch whenever either input changes. This pattern abandons Vue's automatic caching, runs unnecessary code on every keystroke, and creates a synchronization hazard where the flag and the inputs can drift out of sync if multiple paths mutate the data. Another red flag is claiming that watchers are more explicit or easier to read for simple validation; this signals a misunderstanding of Vue's declarative paradigm and leads to spaghetti logic over time. Finally, proposing to mutate the DOM directly inside a watcher instead of letting Vue's template reactivity handle the error message display is a serious anti-pattern that breaks Vue's abstraction.
LIKELY FOLLOW-UPS: The interviewer may ask how you would debounce async validation, which is a legitimate use case for a watcher combined with a timer or a utility like useDebounceFn. They might also ask how to handle cross-field validation in a larger form without a library, prompting a discussion about extracting validation into composables or using a single computed object that returns multiple error states. Another follow-up is whether you would use v-model modifiers like lazy or trim, and how those interact with computed setters for two-way validation scenarios.
ONE CONCRETE EXAMPLE: In the Composition API, you would define const passwordsMatch = computed(() => password.value === confirmPassword.value) and bind the error paragraph to v-if="!passwordsMatch". If you used a watcher instead, you would write watch([password, confirmPassword], ([p, c]) => { isMatch.value = p === c }), which is longer, uncached, and requires an extra isMatch ref that serves no independent purpose. The computed version is the idiomatic Vue solution.
Read the original → vuejs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.