The core values of object-oriented programming include reusing properties and resources and defining relationships between different classes or components. Vue provides two systems that allow us to easily reuse and define relationships between the various components in our code: inheritance and composition.
Inheritance involves creating a new class, the derived class, which is based on an existing base class. The derived class inherits the properties and methods of the base class and can also add its own properties and methods. With inheritance, we can reuse code easily and create a hierarchical class structure.
Composition, on the other hand, allows for greater flexibility and modularity in our code, allowing us to swap components in and out as needed. Composition involves creating a new class by combining multiple other classes, known as component classes. The new class contains instances of the component classes as properties and delegates functionality to them as needed.
Both inheritance and composition have their strengths and weaknesses. When deciding on an approach to use, you need to take your program’s specific design goals and requirements into consideration. In general, inheritance helps to create hierarchical class structures with shared behavior, while composition is more useful for creating flexible and modular systems that can be easily modified and extended.
In this article, we’ll explore composition and inheritance in Vue in greater detail. Let’s get started!
Jump ahead:
In Vue, inheritance allows you to create a hierarchy of components where a child component inherits properties and behaviors from its parent component. This helps to avoid code duplication, making your code more modular and reusable.
To achieve inheritance in Vue, we can use the extends
option, which allows a child component to inherit the properties of its parent component. These properties can include data, computed properties, methods, and lifecycle hooks.
When a child component extends a parent component, it inherits all the properties defined in the parent component, adding or overriding its own properties as needed. Any data or methods defined in the parent component are automatically available in the child component and are accessible using the this
keyword. For example, if the parent component has a data
property called message
, the child component can access it using this.message
.
The examples below show how inheritance works in Vue between parent and child components, respectively:
// Define the parent component ParentComponent.vue
<script>
export default {
data: () => ({
name: "parent component",
}),
};
</script>
// Define the child component and extend the parent component ChildComponent.vue <template> <p>I am the child of the {{ name }}</p> </template> <script>
In the examples, the parent component defines a data
property called name
. The child component extends the parent component and uses the property to display a message as if the name
property was defined on itself.
One caveat to look out for when using inheritance in Vue is that component level properties and methods always override inherited properties and methods. Therefore, if the parent component and child component create a property or method with the same name, the one in the child component always takes precedence.
Inheritance allows you to create a hierarchy of components where a child component inherits properties and behaviors from its parent component using the extends
option, making your code more modular and reusable.
Composition in Vue involves combining smaller, reusable components together to create more complex ones. To achieve composition, we can use Vue composables, which are small, fragmented pieces of logic and reactive properties that a more complex component can use to enhance itself. They allow us to create abstractions and encapsulations around logic by breaking the logic into reusable fragments.
Composables are functions that return an object of reactive properties and methods. We can use them in Vue components by importing them, calling the functions, and accessing the properties that they return.
Typically, composables are prefixed with use
to distinguish them from regular functions. While this isn’t required to make composables work, it is a convention that is agreed upon by Vue developers, making your code easier to read. This naming convention was adopted from React Hooks, which offer similar features and also allow you to use the logic provided by the composable.
The code below shows an example of a simple Vue composable:
// useRandomString import { ref } from "vue"; export const useRandomString = () => { const randomNumber = ref(""); const generator = () => { let string = "abcdefghijklmnopqrstuvwxyz0123456789"; randomNumber.value = ""; for (let i = 0; i < 10; i++) { randomNumber.value += string[Math.floor(Math.random() * 10 + 1)]; } }; return { randomNumber, generator }; };
In the code snippet above, we define a composable called useRandomString
. The function returns a ref
called randomNumber
and a function to generate random numbers, called generator
. generator
exposes the random numbers to any component that composes itself with the composable. Therefore, we can extract the logic and reuse it on any other component that we want to generate random strings:
<template> <div> <h1>{{ randomNumber }}</h1> <button @click="generator()">Generate Random Number </button> </div> </template> <script setup> import { use RandomString } from "@/views/guest/useRandomString"; const { randomNumber , generator } = useRandomString(); </script>
In the code snippet above, we define a component that uses useRandomNumber
. This component will work without knowing how the random number is generated.
Now that we understand how inheritance and composition both work in Vue, let’s compare how both processes handle certain tasks.
Inheritance allows code reuse by inheriting properties and methods from a parent component. Composition, however, is simply a way to reuse code by composing smaller, reusable components and functions.
Inheritance can create tight coupling between components, so modifying or extending them is a bit difficult. Composition promotes loose coupling between components, making them more modular and easier to maintain.
Inheritance can make it difficult to extend components because changes to the parent component can affect the behavior of the child components. On the other hand, with composition, it is easier to extend components by composing smaller, more focused components.
Composition provides greater flexibility than inheritance, as components can be composed differently to achieve different functionality. On the other hand, inheritance can be more rigid as it relies on the structure of the component hierarchy.
Inheritance relies on a hierarchical component structure where child components inherit properties and methods from their parent components. Note that composition allows components to be composed and decomposed without relying on a strict component hierarchy.
In this article, we explored inheritance and composition in Vue, considering their use cases, implementation, and pros and cons. Both systems allow you to easily reuse component logic and define relationships between them. However, while inheritance relies on a component hierarchy, composition doesn’t. Therefore, composition generally offers more flexibility.
You should review the suggested use cases for both inheritance and composition and take your unique project into consideration before making a decision. Hopefully, this article will be of some assistance to you. Happy coding!
Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens in your Vue apps, including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.
The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error and what state the application was in when an issue occurred.
Modernize how you debug your Vue apps — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowThe useReducer React Hook is a good alternative to tools like Redux, Recoil, or MobX.
Node.js v22.5.0 introduced a native SQLite module, which is is similar to what other JavaScript runtimes like Deno and Bun already have.
Understanding and supporting pinch, text, and browser zoom significantly enhances the user experience. Let’s explore a few ways to do so.
Playwright is a popular framework for automating and testing web applications across multiple browsers in JavaScript, Python, Java, and C#. […]