A higher-order component (HOC) is a way to reuse component logic by wrapping one component inside another. It helps keep your code clean and organized.
Higher-order components concept in Vue
const EnhancedComponent = (BaseComponent) => { return { components: { BaseComponent }, setup(props, { attrs, slots }) { // shared logic here return () => h(BaseComponent, { ...attrs }, slots) } } }
The HOC is a function that takes a component and returns a new component.
Use h() to render the wrapped component inside the new one.
const withLogger = (BaseComponent) => { return { setup(props, { attrs, slots }) { return () => { console.log('Component rendered') return h(BaseComponent, { ...attrs }, slots) } } } }
const withLoading = (BaseComponent) => { return { data() { return { loading: true } }, mounted() { setTimeout(() => { this.loading = false }, 2000) }, render() { if (this.loading) return h('div', 'Loading...') return h(BaseComponent, this.$attrs, this.$slots) } } }
This example creates a higher-order component withBorder that adds a blue border around any component it wraps. We wrap SimpleMessage to get BorderedMessage which shows the message inside a bordered box.
<script setup> import { h } from 'vue' const withBorder = (BaseComponent) => { return { setup(props, { attrs, slots }) { return () => h('div', { style: { border: '2px solid blue', padding: '1rem' } }, [ h(BaseComponent, { ...attrs }, slots) ]) } } } const SimpleMessage = { props: ['msg'], template: `<p>{{ msg }}</p>` } const BorderedMessage = withBorder(SimpleMessage) </script> <template> <BorderedMessage msg="Hello from HOC!" /> </template>
HOCs help keep your code DRY (Don't Repeat Yourself) by sharing logic.
Remember to pass props and slots correctly to the wrapped component.
Vue 3 uses h() function to create elements inside setup or render functions.
Higher-order components wrap other components to add shared logic or styling.
They are functions that return new components wrapping the original ones.
Use HOCs to keep your Vue app clean and reusable.
Practice
Solution
Step 1: Understand what HOCs do
Higher-order components wrap existing components to add extra features without changing the original component.Step 2: Identify the correct purpose
Among the options, only wrapping a component to add shared logic or styling matches the HOC concept.Final Answer:
To wrap a component and add shared logic or styling -> Option CQuick Check:
HOC purpose = wrap and add logic [OK]
- Confusing HOCs with routing or Vue instance creation
- Thinking HOCs manipulate DOM directly
- Believing HOCs replace components instead of wrapping
Solution
Step 1: Review HOC syntax in Vue 3
A HOC is a function that returns a new component wrapping the original. Using setup and render function with h() is correct.Step 2: Check each option
const withLogger = (WrappedComponent) => { return { setup() { return () => h(WrappedComponent) } } } returns a component object with setup returning a render function that renders WrappedComponent, which is correct.Final Answer:
const withLogger = (WrappedComponent) => { return { setup() { return () => h(WrappedComponent) } } } -> Option AQuick Check:
HOC returns component with setup and render [OK]
- Calling setup() directly instead of returning a component
- Using new Vue() in Vue 3 Composition API
- Returning the component function without wrapping
const withBorder = (WrappedComponent) => {
return {
setup() {
return () => h('div', { style: { border: '2px solid red' } }, [h(WrappedComponent)])
}
}
}
const Base = { template: 'Hello
' }
const Enhanced = withBorder(Base)What will
<Enhanced /> render?Solution
Step 1: Understand the HOC rendering
The HOC wraps the WrappedComponent inside a div with a red border style.Step 2: Predict the rendered output
Rendering <Enhanced /> produces a div with red border containing the Base component's paragraph.Final Answer:
<div style="border: 2px solid red"><p>Hello</p></div> -> Option BQuick Check:
HOC adds border div around component [OK]
- Ignoring the wrapping div and expecting only <p>
- Thinking h() cannot wrap components
- Assuming no styles are applied
const withTitle = (WrappedComponent) => {
return {
setup() {
return () => h(WrappedComponent)
}
}
}
const Base = { template: 'Hi
' }
const Enhanced = withTitle(Base)
// Usage: <Enhanced title="Welcome" />What is the problem?
Solution
Step 1: Check prop forwarding in HOC
The HOC returns WrappedComponent but does not forward any props it receives.Step 2: Understand consequence
When using <Enhanced title="Welcome" />, the title prop is lost because it's not passed down.Final Answer:
The HOC does not pass props to WrappedComponent -> Option AQuick Check:
Props must be forwarded in HOCs [OK]
- Forgetting to pass props in render function
- Thinking setup can't return render function
- Believing Base must be a function component
withLoading that shows a loading message while data is loading, then renders the wrapped component with the loaded data. Which approach correctly combines HOC logic with Vue 3 Composition API?Solution
Step 1: Understand HOC with loading logic
The HOC should manage loading state internally and decide what to render based on it.Step 2: Identify correct Vue 3 pattern
Using setup with ref for loading, fetching data, and returning a render function that shows loading or wrapped component with data is correct.Final Answer:
Return a component with setup() that uses ref for loading state, fetches data, and renders loading or wrapped component with props -> Option DQuick Check:
HOC manages state and renders conditionally [OK]
- Changing wrapped component template directly
- Using global variables for state
- Confusing mixins with HOCs
Ready to prove it?
Pass the test and this pattern moves unknown
