Title: Vue Framework — LearnCoachAssist

Q: What is Vue.js?
A: Vue.js is a progressive JavaScript framework for building user interfaces. It is designed to be incrementally adoptable and focuses on the view layer, making it easy to integrate with other libraries or existing projects.

Q: What is the Vue reactivity system?
A: The Vue reactivity system automatically tracks dependencies and updates the DOM when reactive state changes. In Vue 3, it uses Proxy objects (instead of Object.defineProperty in Vue 2) to intercept get/set operations on reactive data.

Q: How do you create a reactive object in Vue 3?
A: Use reactive() from the Composition API:
import { reactive } from 'vue'
const state = reactive({ count: 0, name: 'Vue' })
This returns a deeply reactive proxy of the original object.

Q: What is the difference between ref() and reactive()?
A: ref() wraps a single value (primitive or object) and requires .value to access it in script. reactive() wraps an object and provides direct property access.
const count = ref(0) // count.value
const state = reactive({ count: 0 }) // state.count

Q: What is the Composition API in Vue 3?
A: The Composition API is a set of function-based APIs (ref, reactive, computed, watch, lifecycle hooks) that allow organizing component logic by feature rather than by option type. It is used inside setup() or <script setup>.

Q: What is the Options API in Vue?
A: The Options API organizes component logic into predefined options:
- data() — reactive state
- methods — functions
- computed — derived values
- watch — side effects
- mounted(), etc. — lifecycle hooks

Q: What is the script setup syntax in Vue 3?
A: <script setup> is a compile-time syntactic sugar for the Composition API. Top-level bindings (variables, functions, imports) are automatically exposed to the template. It reduces boilerplate by eliminating the need to return values from setup().

Q: What does the v-if directive do?
A: v-if conditionally renders an element based on a truthy expression. The element is completely destroyed and recreated when the condition toggles:
<p v-if="isVisible">Shown</p>
Use with v-else-if and v-else for multiple conditions.

Q: What is the difference between v-if and v-show?
A: v-if completely adds/removes the element from the DOM (higher toggle cost). v-show always keeps the element in the DOM and toggles its CSS display property (higher initial render cost).
Use v-show for frequent toggling, v-if for conditions that rarely change.

Q: How does the v-for directive work?
A: v-for renders a list of items by iterating over an array or object:
<li v-for="(item, index) in items" :key="item.id">{{ item.name }}</li>
A unique :key attribute is required for efficient DOM patching.

Q: What does v-bind do in Vue?
A: v-bind dynamically binds an HTML attribute or component prop to an expression:
<img v-bind:src="imageUrl">
Shorthand: <img :src="imageUrl">
It can also bind multiple attributes at once using an object: v-bind="attrObject".

Q: How does v-model work?
A: v-model creates a two-way binding between a form input and reactive data:
<input v-model="message">
It is syntactic sugar for :value="message" combined with @input="message = $event.target.value".

Q: What are v-model modifiers?
A: Vue provides built-in modifiers for v-model:
- .lazy — syncs on change instead of input
- .number — casts input to a number
- .trim — trims whitespace from input
Example: <input v-model.trim="name">

Q: What does v-on do in Vue?
A: v-on attaches an event listener to an element:
<button v-on:click="handleClick">Click</button>
Shorthand: <button @click="handleClick">Click</button>
Supports modifiers like .prevent, .stop, .once, and .self.

Q: What are computed properties in Vue?
A: Computed properties are cached reactive derivations. They recompute only when their dependencies change.
Composition API: const fullName = computed(() => first.value + ' ' + last.value)
Options API: defined in the computed option. They should be side-effect free.

Q: What is the difference between computed properties and methods?
A: Computed properties are cached — they only re-evaluate when reactive dependencies change. Methods run on every re-render. Use computed for expensive derivations that depend on reactive state, and methods for event handlers or actions with side effects.

Q: Can computed properties have setters?
A: Yes. A writable computed can define both a getter and setter:
const fullName = computed({
  get: () => first.value + ' ' + last.value,
  set: (val) => { [first.value, last.value] = val.split(' ') }
})

Q: What are watchers in Vue?
A: Watchers perform side effects in response to reactive state changes. In the Composition API, use watch() or watchEffect():
watch(count, (newVal, oldVal) => { console.log(newVal) })
In the Options API, use the watch option.

Q: What is the difference between watch() and watchEffect()?
A: watch() requires you to explicitly specify the source(s) to watch and provides old/new values. watchEffect() automatically tracks all reactive dependencies accessed inside its callback and runs immediately.
watchEffect(() => console.log(count.value))

Q: What are the Vue 3 lifecycle hooks?
A: Key lifecycle hooks in order:
- onBeforeMount — before initial DOM render
- onMounted — after DOM is mounted
- onBeforeUpdate — before re-render
- onUpdated — after re-render
- onBeforeUnmount — before teardown
- onUnmounted — after teardown

Q: When should you use the onMounted hook?
A: Use onMounted when you need access to the rendered DOM, such as:
- Fetching data from an API
- Initializing third-party libraries (charts, maps)
- Setting up event listeners on DOM elements
- Accessing template refs

Q: What is the onUnmounted hook used for?
A: onUnmounted is called after the component is removed from the DOM. Use it for cleanup:
- Removing event listeners
- Clearing timers and intervals
- Cancelling API requests
- Disconnecting WebSocket connections

Q: What are slots in Vue?
A: Slots allow a parent component to pass template content into a child component's designated areas:
<MyCard><p>This goes into the slot</p></MyCard>
The child uses <slot></slot> to render the passed content. They enable flexible, reusable component design.

Q: What are named slots?
A: Named slots allow a component to have multiple slot outlets:
Child: <slot name="header"></slot>
Parent: <template #header><h1>Title</h1></template>
The # symbol is shorthand for v-slot:. Unnamed content goes to the default slot.

Q: What are scoped slots?
A: Scoped slots let a child component pass data back to the parent's slot content:
Child: <slot :item="item"></slot>
Parent: <template #default="{ item }">{{ item.name }}</template>
This enables the parent to customize rendering while the child provides the data.

Q: What is Pinia?
A: Pinia is the official state management library for Vue 3, replacing Vuex. Key features:
- Simpler API with no mutations
- Full TypeScript support
- Composition API and Options API store styles
- DevTools integration
- Modular by design — each store is independent

Q: How do you define a Pinia store?
A: Use defineStore():
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  getters: { double: (state) => state.count * 2 },
  actions: { increment() { this.count++ } }
})

Q: How do you use a Pinia store with the Composition API style?
A: Define with a setup function:
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const double = computed(() => count.value * 2)
  function increment() { count.value++ }
  return { count, double, increment }
})

Q: What are Pinia getters?
A: Getters in Pinia are equivalent to computed properties for stores. They are cached and only recalculate when their dependencies change:
getters: {
  doubleCount: (state) => state.count * 2,
  doubleCountPlusOne() { return this.doubleCount + 1 }
}

Q: What are Pinia actions?
A: Actions in Pinia are methods that can contain business logic and async operations. Unlike Vuex, there are no separate mutations:
actions: {
  async fetchUser(id) {
    this.user = await api.getUser(id)
  }
}

Q: What is Vue Router?
A: Vue Router is the official routing library for Vue.js. It maps URL paths to components, enabling single-page application navigation:
- Nested routes
- Dynamic route matching with params
- Named routes and views
- Navigation guards
- History and hash mode

Q: How do you define routes in Vue Router?
A: import { createRouter, createWebHistory } from 'vue-router'
const routes = [
  { path: '/', component: Home },
  { path: '/user/:id', component: User },
  { path: '/:pathMatch(.*)*', component: NotFound }
]
const router = createRouter({ history: createWebHistory(), routes })

Q: What are dynamic route params in Vue Router?
A: Dynamic segments are defined with a colon prefix: /user/:id. Access params in a component with:
Composition API: const route = useRoute(); route.params.id
Options API: this.$route.params.id
Multiple params are supported: /user/:userId/post/:postId.

Q: What are navigation guards in Vue Router?
A: Navigation guards are hooks that run before or after route changes:
- beforeEach — global, runs before every navigation
- beforeEnter — per-route guard
- beforeRouteEnter / beforeRouteLeave — in-component guards
Used for authentication checks, data fetching, and access control.

Q: How do you navigate programmatically with Vue Router?
A: Use the router instance methods:
const router = useRouter()
router.push('/about') — navigate to a new URL
router.push({ name: 'user', params: { id: 1 } }) — named route
router.replace('/login') — replace without history entry
router.go(-1) — go back

Q: What are emits in Vue?
A: Emits allow a child component to send events to its parent:
Child: const emit = defineEmits(['update'])
emit('update', newValue)
Parent: <Child @update="handleUpdate" />
Emits can include validation to ensure correct payload types.

Q: How do you declare emits with validation?
A: Emits can be validated with an object syntax:
const emit = defineEmits({
  submit(payload) {
    return payload.email && payload.password
  }
})
If the validator returns false, a console warning is emitted in development mode.

Q: What is provide/inject in Vue?
A: provide and inject enable dependency injection across the component tree without prop drilling:
Parent: provide('theme', ref('dark'))
Descendant: const theme = inject('theme')
Works across any depth of nesting, not just direct parent-child.

Q: When should you use provide/inject vs props?
A: Use props for direct parent-child communication. Use provide/inject when:
- Data must pass through many intermediate components (prop drilling)
- Building component libraries with shared context
- Providing app-wide services (theme, locale, auth)
Prefer Pinia for complex shared state.

Q: What are template refs in Vue?
A: Template refs provide direct access to DOM elements or child component instances:
<input ref="inputRef">
const inputRef = ref(null)
onMounted(() => inputRef.value.focus())
Refs are populated after the component is mounted. Use ref on a component to access its exposed methods.

Q: What is defineProps in Vue 3?
A: defineProps declares the props a component accepts in <script setup>:
const props = defineProps({
  title: { type: String, required: true },
  count: { type: Number, default: 0 }
})
It is a compiler macro — no import needed.

Q: What is defineExpose in Vue 3?
A: defineExpose explicitly exposes properties from a <script setup> component to parent template refs:
defineExpose({ reset, validate })
By default, <script setup> components are closed — the parent cannot access internal bindings without defineExpose.

Q: What are custom directives in Vue?
A: Custom directives provide low-level DOM access for reusable behavior:
const vFocus = { mounted: (el) => el.focus() }
Usage: <input v-focus>
Directive hooks mirror lifecycle: created, beforeMount, mounted, beforeUpdate, updated, beforeUnmount, unmounted.

Q: What is the key attribute used for in v-for?
A: The :key attribute gives Vue a unique identity for each list item so it can efficiently patch and reorder DOM elements. Without keys, Vue uses an in-place patch strategy that can cause bugs with stateful elements.
<li v-for="item in items" :key="item.id">

Q: What is toRefs() used for?
A: toRefs() converts a reactive object's properties into individual refs that maintain reactivity when destructured:
const state = reactive({ name: 'Vue', version: 3 })
const { name, version } = toRefs(state)
Without toRefs, destructured values lose their reactive connection.

Q: What is shallowRef() in Vue?
A: shallowRef() creates a ref that is only reactive at the top level. Nested property changes are not tracked:
const state = shallowRef({ nested: { count: 0 } })
state.value.nested.count++ — won't trigger updates
state.value = { nested: { count: 1 } } — triggers update. Useful for performance optimization.

Q: What are async components in Vue?
A: Async components are loaded on demand using defineAsyncComponent:
const AsyncModal = defineAsyncComponent(() => import('./Modal.vue'))
They support options for loading and error components, delay, and timeout. Combined with Vue Router, they enable code splitting and lazy loading.

Q: How do you handle events with modifiers in Vue?
A: Event modifiers simplify common event handling patterns:
- @click.prevent — calls preventDefault()
- @click.stop — calls stopPropagation()
- @click.once — triggers only once
- @keyup.enter — listens for Enter key
- @click.self — only if target is the element itself

Q: What is Teleport in Vue?
A: <Teleport> renders a component's content in a different DOM location than its logical parent:
<Teleport to="body"><div class="modal">...</div></Teleport>
Useful for modals, tooltips, and notifications that need to break out of parent CSS constraints like overflow: hidden.

Q: What is Suspense in Vue 3?
A: <Suspense> orchestrates async dependencies in a component tree. It shows fallback content while waiting for async components or async setup():
<Suspense>
  <template #default><AsyncChild /></template>
  <template #fallback>Loading...</template>
</Suspense>