
Vue Basis: How to Create Reusable Input Component
In real-world commercial projects, it's common to encounter designs featuring identical styled components and functionalities. Writing extensive lines of code for each instance can be tedious, and the quest for an efficient solution becomes paramount. Enter the concept of reusable components—a boon for developers seeking both flexibility and functionality in their codebase. In this post, we'll embark on a journey to create a versatile and reusable input component for our Vue.js project. Discover how to streamline your code and enhance project efficiency by implementing a single, adaptable input solution wherever it's needed! So let's do it:
I will create a new project for testing purposes by using the instructions from my previous post. If you do not have a project you can do the same. After we create a project and remove unneeded components, we can add some styles and dive into coding.
Setting Up the Project
So we will create a "MainInput.vue" component where we will add one input and borrow styles from UI Verse.
<template>
<input class="input" placeholder="text">
</template>
<script>
export default {
name: 'MainInput',
}
</script>
Then in our "App.vue" file, we will import "MainInput.vue" component and also add some styles like gradient and glassmorphism for better UI.
<template>
<main>
<div class="container">
<h1>Vue Input Component</h1>
<div class="input-wrapper">
<MainInput />
</div>
</div>
</main>
</template>
<script>
import MainInput from './components/MainInput.vue';
export default {
name: 'App',
components: {
MainInput
}
}
</script>
Okay, now our project and input are ready for the next steps.
We have an input that could be imported wherever we want, so it's already reusable. But not really! We need to implement a possibility to work with data and update some styles dynamically.
Implementing Data Binding
First, data. We need our component to receive data from the user and send that data to the parent component, also that would be great if our input component could receive data from the app (if we would like to update data from the database for example) and react to users' updates. We will not use "v-model" directive but will directly bind our input "value" attribute and we will add "v-on:input" listener to react to user updates that will be sending data directly to the parent component. Also, we need to receive data from the parent app, so we will add an "inputValue" as props. Here how it will look like:
<template>
<input class="input"
placeholder="text"
type="text"
:value="inputValue"
v-on:input="$emit('update:inputValue', $event.target.value)">
</template>
<script>
export default {
name: 'MainInput',
props: {
inputValue: {
type: String,
required: false
}
}
}
</script>
In the parent app, we will send data as props and listen for events from the child component. Here is how it will be changed:
<template>
<main>
<div class="container">
<h1>Vue Input Component</h1>
<div class="input-wrapper">
<MainInput
:inputValue="inputValue"
@update:inputValue="inputValue = $event"/>
</div>
</div>
</main>
</template>
<script>
import MainInput from './components/MainInput.vue';
export default {
name: 'App',
components: {
MainInput
},
data() {
return {
inputValue: ''
}
}
}
</script>
Great! Now we can copy and paste our input wherever we want in a project only updating data value and it will work correctly.
Adding Flexibility with Props
Also, we might need our input to look a little bit different in different situations, for example, different colors, style (width, height), placeholder... We can achieve that with additional props with default values. Let's add those props into our input component:
<template>
<input class="input"
:placeholder="placeholder"
:type="type"
:style="`width: ${width}; border-color: ${borderColor}`"
:value="inputValue"
v-on:input="$emit('update:inputValue', $event.target.value)">
</template>
<script>
export default {
name: 'MainInput',
props: {
inputValue: {
type: String,
required: false
},
placeholder: {
type: String,
required: false,
default: 'Type here...'
},
type: {
type: String,
required: false,
default: 'text'
},
width: {
type: String,
required: false,
default: '200px'
},
borderColor: {
type: String,
required: false,
default: '#4A9DEC'
}
}
}
</script>
In "App.vue" file we will add a few "MainInput" components with different props for testing.
<template>
<main>
<div class="container">
<h1>Vue Input Component</h1>
<div class="input-wrapper">
<MainInput
:inputValue="inputValue"
@update:inputValue="inputValue = $event"/>
<MainInput
:width="'250px'"
:borderColor="'red'"
:placeholder="'Search here...'"
:inputValue="search"
@update:inputValue="search = $event"/>
<MainInput
:type="'email'"
:placeholder="'Enter your email...'"
:width="'300px'"
:borderColor="'blue'"
:inputValue="email"
@update:inputValue="email = $event"/>
</div>
</div>
</main>
</template>
<script>
import MainInput from './components/MainInput.vue';
export default {
name: 'App',
components: {
MainInput
},
data() {
return {
inputValue: '',
search: '',
email: ''
}
}
}
</script>
Each input component will have a different view and data. As in the "result" screen below:

In this journey of creating a reusable input component in Vue.js, we've unlocked the potential of streamlining our projects. By encapsulating functionalities and flexibility within a single component, we've witnessed the power of reusability in action. From establishing the foundational structure to enhancing its adaptability through props, our Vue input component now stands as a versatile tool ready for seamless integration wherever it's needed. Embracing this approach not only simplifies our code but also empowers us to craft efficient, scalable Vue.js applications. With this newfound understanding, incorporating reusable components becomes a cornerstone in optimizing development workflows and fostering project efficiency.
Related
How to Add a QR Code Scanner in Vue.js (Step-by-Step Guide)
Starting out in programming is thrilling, yet the number of languages available makes it difficult to decide where to begin.
Building Simple CRM with Vue: Crafting Layouts and Navigation
Starting out in programming is thrilling, yet the number of languages available makes it difficult to decide where to begin.
Full-Stack Blogging CMS: A 17-Part Journey
Starting out in programming is thrilling, yet the number of languages available makes it difficult to decide where to begin.
Start the conversation