1. Which interpolation syntax is called “Mustache” in Vue?
Mustache syntax {{ }} renders reactive values into templates.
<p>{{ message }}</p>Get the Preplance app for a seamless learning experience. Practice offline, get daily streaks, and stay ahead with real-time interview updates.
Get it on
Google Play
4.9/5 Rating on Store
Amazon · Vue Js
Practice Vue Js questions specifically asked in Amazon interviews – ideal for online test preparation, technical rounds and final HR discussions.
Questions
37
Tagged for this company + subject
Company
Amazon
View company-wise questions
Subject
Vue Js
Explore topic-wise practice
Go through each question and its explanation. Use this page for targeted revision just before your Amazon Vue Js round.
Mustache syntax {{ }} renders reactive values into templates.
<p>{{ message }}</p>For complete preparation, combine this company + subject page with full company-wise practice and subject-wise practice. You can also explore other companies and topics from the links below.
Use modern formats (WebP/AVIF), responsive sizes (srcset/sizes), lazy-loading (loading="lazy"), and cache headers/CDN. Defer non-critical assets and prefetch route chunks for perceived speed.
v-if adds or removes elements from the DOM based on a condition.
data() returns a fresh object that Vue makes reactive for each component instance. Returning a factory function avoids shared state across instances. Properties returned from data() are tracked; updates automatically re-render the template.
export default {
name: 'ExampleComponent',
data(){
return { message: 'Hello', count: 0 }
}
}One-way binding (v-bind or :) updates the view from data. Two-way binding (v-model) keeps input elements and component state in sync. Use v-bind for attributes and v-model for form fields that users edit.
<p :title="message">{{ message }}</p>
<input v-model="userInput">Vue CLI bootstraps projects with modern tooling and presets.
Use v-on (or @) to listen to DOM events like click or input.
<button v-on:click="save()">Save</button>
Use a props object with type, required, default, and validator. Validation catches incorrect usage early; defaults make components resilient and self-documenting. For object/array defaults, return a factory function to avoid shared references.
props: {
options: {
type: Array,
default: () => []
},
mode: {
type: String,
validator: v => ['light','dark'].includes(v)
}
}Slots let parents inject markup into a child component’s template. A default slot is unnamed and fills the primary content area. Named slots provide multiple targeted insertion points using <slot name="..."> and template v-slot:name in the parent.
<!-- Child.vue --> <template> <header><slot name="header" /></header> <main><slot /></main> <footer><slot name="footer" /></footer> </template> <!-- Parent.vue --> <Card> <template #header>Title</template> Body content <template #footer>Actions</template> </Card>
The Virtual DOM is an in-memory tree describing the UI. On state changes, Vue diffs the new tree against the previous one and applies the minimal set of real DOM operations. This reduces layout thrashing and enables batched, predictable updates.
key gives Vue a stable identity for each node so it can efficiently reuse and reorder DOM elements. Use a unique, stable key like an id; avoid array indexes when items can be reordered/removed to prevent incorrect state reuse.
<li v-for="todo in todos" :key="todo.id">{{ todo.text }}</li>Use the object syntax with options: { deep: true } to traverse nested properties (be mindful of performance), and { immediate: true } to run the callback right after the watcher is registered.
watch: {
settings: {
deep: true,
immediate: true,
handler(val){ console.log('settings changed', val) }
}
}Use custom events for direct parent–child communication. Event buses (Vue 2 pattern) can create hidden coupling and are discouraged in larger apps—prefer Vuex/Pinia for many-to-many communication or deeply nested siblings. Stores keep flows predictable and testable.
Creation: beforeCreate/created (or setup in Vue 3) for initializing data, starting requests. Mounting: beforeMount/mounted for DOM-dependent work. Updating: beforeUpdate/updated for reacting to re-renders. Unmounting: beforeUnmount/unmounted (Vue 3) or beforeDestroy/destroyed (Vue 2) for cleanup like removing listeners or canceling timers.
Use component-level try/catch, the errorCaptured hook to catch errors from child components, and global handlers (app.config.errorHandler in Vue 3) for app-wide logging and recovery. For async code, handle rejections with try/catch or .catch.
Vue 3 allows multiple v-models by naming them, e.g., v-model:title and v-model:content. Use this to keep separate pieces of state in sync (like title and body) without packing into a single object.
<PostEditor v-model:title="title" v-model:content="content" />
Debounce user input, call an API, then set an error state on the field based on the response. Cancel stale requests via AbortController or a request token to avoid race conditions, and show inline feedback and a neutral state while checking.
let ctrl: AbortController | null = null
async function checkEmail(email:string){
ctrl?.abort(); ctrl = new AbortController()
const res = await fetch(`/api/exists?email=${email}`, { signal: ctrl.signal })
state.emailError = (await res.json()).exists ? 'Email already used' : ''
}Pair labels with inputs via for/id, use fieldset/legend for groups, aria-invalid/aria-describedby for errors, and proper roles on custom widgets. Manage focus on submit errors and ensure keyboard navigation works across all custom inputs.
computed() derives a value from reactive sources and caches the result until dependencies change. Methods re-run every call. Use computed for derived data (filters, totals, formatting) and methods for actions.
import { ref, computed } from 'vue'
const first = ref('Ada'), last = ref('Lovelace')
const full = computed(() => `${first.value} ${last.value}`)immediate: true runs the watcher once on setup with the current value. deep: true traverses nested objects/arrays so changes to inner properties trigger the watcher. Deep should be used carefully due to performance cost.
watch(state, (nv, ov) => save(nv), { deep: true, immediate: true })Pass an array of sources to watch. The callback receives arrays of new and old values in the same order. Sources can be refs, computed, or getter functions.
watch([() => route.params.id, filters], ([id, fNew], [prevId, fOld]) => {
fetchList(id, fNew)
}).trim removes surrounding whitespace from input values, .number casts numeric strings to numbers, and .lazy updates the model on change instead of on each input event (useful for performance or when you need commit-like behavior).
<input v-model.trim="name"> <input v-model.number="age"> <input v-model.lazy="query">
Prevent default, validate synchronously, then run async validations if any. Show a loading state, call the API, handle success (reset/redirect) and failure (map server errors to fields). Always clear the loading state in a finally block.
const submitting = ref(false)
async function onSubmit(e){
e.preventDefault()
if(!canSubmit.value) return
submitting.value = true
try { await api.save(form) }
catch(err){ mapErrors(err) }
finally { submitting.value = false }
}setup() runs before component creation and has no this. You declare reactive state (ref/reactive), computed values, watchers, and methods. Return an object to expose bindings to the template (or use <script setup> which auto-exposes top-level bindings).
import { ref, computed } from 'vue'
export default {
setup(){
const count = ref(0)
const double = computed(() => count.value * 2)
function inc(){ count.value++ }
return { count, double, inc }
}
}toRefs() converts each property of a reactive object into a ref, preserving reactivity when destructuring. toRef(obj, key) creates a single ref pointing to a specific property. Without these, destructuring a reactive object breaks reactivity.
const state = reactive({ first: 'Ada', last: 'Lovelace' })
const { first, last } = toRefs(state)
// first.value stays in sync with state.firstprovide() registers a value on an ancestor; inject() reads it from descendants without prop drilling. It’s ideal for theming, i18n, or shared services. Avoid overuse for ordinary parent-child data—props/emit are still clearer for local communication.
provide('theme', themeRef)
// descendant
const theme = inject('theme', ref('light'))v-show toggles CSS display and keeps the element in the DOM—best for frequent toggling (e.g., tabs, dropdowns). v-if adds/removes nodes, which is more expensive when toggled often. Use v-if for rarely shown content to avoid initial render cost.
Wrap the effect (API call or filter) in a debounced function or use watch with a debounce scheduler. This reduces update frequency, saving CPU and network.
watch(query, debounce((q)=> fetch(q), 300))
Pass different prop values to verify rendering/validation branches. Trigger user interactions and assert wrapper.emitted('eventName') payloads. Use shallowMount when child rendering is irrelevant.
Use E2E for user flows across pages: routing, forms, auth, and API integration. Assert URL changes, visible text, network stubs, and accessibility. Keep tests resilient by using data-testid selectors.
Put variables in .env, .env.development, .env.production, and prefix with VITE_. Access via import.meta.env. Never expose secrets; keep private keys server-side.
Caching avoids re-running expensive logic on every render.
For a single checkbox, it binds a boolean. For multiple checkboxes with the same v-model, it pushes/pulls values from an array. For radio buttons, it binds the selected radio’s value to a single scalar.
<input type="checkbox" v-model="isAdmin">\n<input type="checkbox" v-model="skills" value="js">\n<input type="checkbox" v-model="skills" value="vue">\n<input type="radio" v-model="level" value="junior">
1) A ref unwrapped inside reactive becomes a plain value—updates to the original ref won’t propagate unless you keep it as a ref property (e.g., state.count = ref(0)). 2) Destructuring reactive objects breaks reactivity; use toRefs() to preserve it.
import { reactive, toRefs, ref } from 'vue'
const inner = ref(1)
const state = reactive({ a: inner }) // inner unwrapped here
const { a } = toRefs(state) // keep reactivity when destructuringImplement a prop named modelValue and emit an update:modelValue event when internal state changes. Consumers can then use v-model on your component. You can also support multiple v-model bindings with the v-model:arg syntax.
// Child
export default {
props: { modelValue: String },
emits: ['update:modelValue']
}
// Template
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />Keep raw form state in refs/reactive, then compute an errors map by deriving rules (required, length, regex). Disable submit if errors exist and show messages next to inputs.
const form = reactive({ email: '', pwd: '' })
const errors = computed(() => ({
email: /.+@.+\..+/.test(form.email) ? '' : 'Enter a valid email',
pwd: form.pwd.length >= 8 ? '' : 'Min 8 chars'
}))
const canSubmit = computed(() => !errors.value.email && !errors.value.pwd)Wrap a dynamic import with defineAsyncComponent and provide loading/error components and delays/timeouts. Pair with <Suspense> for async setup. This splits code and reduces initial bundle size.
import { defineAsyncComponent } from 'vue'
const Chart = defineAsyncComponent({
loader: () => import('./Chart.vue'),
loadingComponent: () => import('./Loading.vue'),
delay: 200,
timeout: 10000
})