Vue.js Developer Certification — Questions and Answers
Question 1: In Vuex 4, what is a mutation and why must state changes go through it?
- A synchronous function that is the only valid way to change Vuex state, enabling devtools tracking (Correct answer)
- An async API call handler
- A plugin hook for middleware
- A computed property for the store
Correct answer: A synchronous function that is the only valid way to change Vuex state, enabling devtools tracking
Mutations are synchronous functions that directly modify state, and Vuex enforces this pattern so every change is trackable in Vue Devtools.
Question 2: What happens when you destructure a property from a reactive() object in Vue 3?
- The property remains reactive
- The property loses its reactivity (Correct answer)
- The property becomes a computed ref
- Vue throws a warning
Correct answer: The property loses its reactivity
Destructuring a property from a reactive object copies its primitive value, breaking the Proxy link and losing reactivity.
Question 3: How do you stop a watcher created inside setup() from running?
- Watchers cannot be manually stopped
- Set the source ref to null
- Call the stop function returned by watch()/watchEffect() (Correct answer)
- Use onUnmounted() with clearWatch()
Correct answer: Call the stop function returned by watch()/watchEffect()
watch() and watchEffect() both return a stop function that, when called, removes the watcher.
Question 4: How can Pinia store actions be tested in isolation without mounting a Vue component?
- Only Vuex stores can be tested in isolation
- Create a Pinia instance with createPinia(), install it with setActivePinia(), then call the store composable directly (Correct answer)
- Actions cannot be tested without a component
- Use jest.mock() to replace the entire store
Correct answer: Create a Pinia instance with createPinia(), install it with setActivePinia(), then call the store composable directly
setActivePinia(createPinia()) sets up a fresh Pinia context so you can instantiate and test stores directly in Jest/Vitest without a Vue app.
Question 5: What is the purpose of Vue.js?
- The creation of user interfaces usually makes use of this dynamic JavaScript framework. (Correct answer)
- With the help of a JavaScript library, it is possible to create user interfaces for single-page applications by breaking the UI up into modular parts.
- It ties data to specific DOM elements using the MVVM paradigm.
- All of the above
Correct answer: The creation of user interfaces usually makes use of this dynamic JavaScript framework.
Vue.js is primarily used for building interactive and dynamic user interfaces (UIs) and single-page applications (SPAs). It provides a reactive data-binding system and a component-based architecture that simplifies the development of complex front-end applications, allowing developers to efficiently manage the view layer of their web applications.
Question 6: How do you provide a default value for a named slot in Vue 3?
- Use v-slot:header="default"
- Set a prop with the slot name
- Place fallback content between the <slot> tags: <slot name="header">Default Header</slot> (Correct answer)
- Use the default attribute: <slot name="header" default="Default Header">
Correct answer: Place fallback content between the <slot> tags: <slot name="header">Default Header</slot>
Content placed between `<slot>` tags acts as fallback/default content rendered when the parent provides no slot content.
Question 7: In Pinia, how do stores communicate with each other (cross-store actions)?
- Import and use another store's composable inside the first store's actions or getters (Correct answer)
- Stores cannot communicate directly in Pinia
- Register all stores as Vuex modules
- Use a global event bus
Correct answer: Import and use another store's composable inside the first store's actions or getters
Because Pinia stores are composables, you can simply import and call another store inside any store's actions or getters, creating straightforward cross-store dependencies.
Question 8: How does a child notify its parent that something happened?
- By returning a value from data()
- By importing the parent
- By mutating the parent's data directly
- By calling $emit with an event name (Correct answer)
Correct answer: By calling $emit with an event name
Children use $emit to fire events that parents listen for with v-on.
Question 9: How do you provide a mock value for a dependency injected with inject() in a unit test?
- Overwrite the inject() function globally
- Injected values cannot be mocked in tests
- Pass it as a component prop in mount()
- Use the global.provide option in mount() to supply mock values at the test root (Correct answer)
Correct answer: Use the global.provide option in mount() to supply mock values at the test root
The global.provide option in @vue/test-utils mount() makes the specified values available to inject() calls throughout the component tree under test.
Question 10: How does FormKit differ from VeeValidate for Vue 3 form handling?
- FormKit requires a backend; VeeValidate is frontend-only
- There is no functional difference
- FormKit is for React; VeeValidate is for Vue
- FormKit provides complete form components (inputs, selects, etc.) with built-in validation; VeeValidate is a validation-only library that wraps your own inputs (Correct answer)
Correct answer: FormKit provides complete form components (inputs, selects, etc.) with built-in validation; VeeValidate is a validation-only library that wraps your own inputs
FormKit is a full form-building framework providing styled, accessible input components with integrated validation, theming, and plugins. VeeValidate is focused solely on validation logic.
Question 11: What is the recommended way to name a single-file component file?
- MyComponent.vue (PascalCase) (Correct answer)
- Component.js
- mycomponent.html
- my_component.vue
Correct answer: MyComponent.vue (PascalCase)
Vue style guide recommends PascalCase single-file component filenames ending in .vue.
Question 12: What Vuex concept did Pinia intentionally remove to simplify the API?
- Mutations (Correct answer)
- Actions
- Getters
- State
Correct answer: Mutations
Pinia removed mutations entirely. In Pinia, actions can directly modify state both synchronously and asynchronously, eliminating the verbose mutations layer.
Question 13: What is a dynamic component rendered with in Vue?
- <component :is="name"> (Correct answer)
- <dynamic>
- <switch>
- <v-render>
Correct answer: <component :is="name">
The built-in <component> element with :is renders a component chosen at runtime.
Question 14: What Vue 3 function lets you run a side effect whenever its reactive dependencies change?
- onMounted()
- watchEffect() (Correct answer)
- watch()
- computed()
Correct answer: watchEffect()
watchEffect() immediately runs a function and automatically re-runs it whenever any reactive dependency accessed inside it changes.
Question 15: How do you expose specific properties and methods to parent components in `<script setup>`?
- All bindings in <script setup> are automatically exposed
- Using the expose option in defineOptions
- Returning them from setup()
- Using defineExpose({ property, method }) (Correct answer)
Correct answer: Using defineExpose({ property, method })
`defineExpose` explicitly declares what a component with `<script setup>` exposes to parent components via template refs. By default, nothing is exposed.
Question 16: Which directory commonly holds shared UI components in a Vue project?
- src/assets
- src/components (Correct answer)
- node_modules
- public
Correct answer: src/components
By convention reusable components live in the src/components directory.
Question 17: Describe Vue.js.
- It is a JavaScript library constructed to facilitate HTML DOM tree traversal and administration, and event handling, CSS activity, and Ajax.
- It is an open-source front-end JavaScript framework for developing user interfaces. (Correct answer)
- It is an open-source JavaScript library for developing user interfaces.
- It is an open-source, cross-platform, JavaScript run-time situations that perform the JavaScript program outside a web browser.
Correct answer: It is an open-source front-end JavaScript framework for developing user interfaces.
Vue.js is a progressive, open-source JavaScript framework specifically designed for building user interfaces and single-page applications. It focuses on the view layer, making it easy to integrate into existing projects or use for complex front-end development. Its reactivity system and component-based architecture are key features.
Question 18: How can you use ES6 destructuring with scoped slot props?
- <template v-slot:default [item, index]>{{ item }}</template>
- <template v-slot:default="{ item, index }">{{ item }}</template> (Correct answer)
- <template v-slot:default="props" :destructure="props">{{ props.item }}</template>
- <template v-slot:default destructure="item, index">{{ item }}</template>
Correct answer: <template v-slot:default="{ item, index }">{{ item }}</template>
JavaScript destructuring syntax works directly inside the v-slot value, allowing you to extract only the specific slot props you need.
Question 19: How do you test a Vue composable (Composition API function) without mounting a full component?
- Use the Options API wrapper pattern only
- Composables must be tested inside a component
- Wrap the call in withSetup() or call it directly if it has no lifecycle dependencies (Correct answer)
- Run composables in a Web Worker for isolation
Correct answer: Wrap the call in withSetup() or call it directly if it has no lifecycle dependencies
Simple composables with no lifecycle hooks can be called directly in tests; for those needing lifecycle context, a helper app/component wrapper provides the correct Vue instance.
Question 20: What is the recommended way to initialize a third-party JavaScript library that needs a DOM element in Vue 3?
- Initialize it inside onMounted using a template ref to target the DOM element (Correct answer)
- Initialize in setup() before returning
- Initialize in onBeforeMount
- Initialize in the component's data() function
Correct answer: Initialize it inside onMounted using a template ref to target the DOM element
`onMounted` is the earliest point where the DOM element exists. Using a template ref to get the DOM node and initializing the library there is the standard pattern.
Question 21: What is the difference between mount() and shallowMount() in @vue/test-utils?
- mount() fully renders child components; shallowMount() stubs child components (Correct answer)
- mount() is for Vue 3; shallowMount() is for Vue 2
- shallowMount() runs faster because it uses SSR
- mount() requires a real browser; shallowMount() runs in Node
Correct answer: mount() fully renders child components; shallowMount() stubs child components
shallowMount() replaces all child components with stubs so tests focus on the component under test without being affected by child component behavior.
Question 22: Which option in a Vue component holds reactive state when using the Options API?
- props()
- reactive()
- state()
- data() (Correct answer)
Correct answer: data()
The data() function returns an object whose properties become reactive component state.
Question 23: How do you use the Composition API in a Vue 3 component that still uses the Options API?
- Composition API cannot be mixed with Options API
- Replace all options with Composition API functions
- Add a setup() function to the Options API component — it runs before other options and can return values used by them (Correct answer)
- Use a separate <script setup> alongside the existing Options API
Correct answer: Add a setup() function to the Options API component — it runs before other options and can return values used by them
A `setup()` function can coexist with Options API options in Vue 3. It runs first and can return values accessible by the Options API and template.
Question 24: What does `toRefs` do in Vue 3?
- Converts a reactive object's properties into individual refs, preserving reactivity when destructured (Correct answer)
- Removes reactivity from a reactive object
- Converts refs into a reactive object
- Converts computed values to refs
Correct answer: Converts a reactive object's properties into individual refs, preserving reactivity when destructured
`toRefs` converts each property of a reactive object into a separate ref, so destructuring the result maintains reactivity.
Question 25: How do you create a custom directive that only runs on the element's `updated` hook?
- app.directive('myDir').onUpdate((el) => { ... })
- app.directive('myDir', { updated(el, binding) { ... } }) (Correct answer)
- v-on:update.myDir="handler"
- app.directive('myDir', (el, binding) => { ... }) — the function shorthand runs on mounted AND updated
Correct answer: app.directive('myDir', { updated(el, binding) { ... } })
Custom directives with the `updated` hook only run when the element's containing component re-renders after an update, not on initial mount.
Question 26: What is the purpose of key modifiers in Vue 3 event handling, e.g., `@keyup.enter`?
- They define keyboard shortcuts for the application
- They bind keyboard events to native DOM properties
- They prevent default behavior for specific keys
- They filter keyboard events to only fire the handler when the specified key is pressed (Correct answer)
Correct answer: They filter keyboard events to only fire the handler when the specified key is pressed
Key modifiers filter keyboard events. `@keyup.enter` only calls the handler when the Enter key is released, avoiding the need for manual `event.key` checks in the handler.
Vue.js Developer Certification
The official Vue.js Developer Certification tests competency in building reactive web applications with Vue 3, covering core concepts, components, the Composition API, reactivity, and the broader Vue ecosystem. Developed in collaboration with Evan You and the Vue.js core team via Certificates.dev.
Exam Rules
- You can skip questions and return to them later
- Flag questions for review before submitting
- No feedback shown until you submit the entire exam
- Unanswered questions count as wrong — answer everything
- 10 pretest questions are mixed in and don't affect your score
- Timer auto-submits when time runs out
- Your progress is auto-saved every 30 seconds