DEV Community

WebCraft Notes
WebCraft Notes

Posted on • Edited on • Originally published at webcraft-notes.com

Vue Basis: How to Create Reusable Input Component

Vue Basis: How to Create Reusable Input Component

Check this post in my web notes

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

Continue reading...

Billboard image

The fastest way to detect downtimes

Join Vercel, CrowdStrike, and thousands of other teams that trust Checkly to streamline monitoring.

Get started now

Top comments (0)

nextjs tutorial video

📺 Youtube Tutorial Series

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series

👋 Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay