Vue.js Articles / Blogs / Perficient https://blogs.perficient.com/tag/vue-js/ Expert Digital Insights Thu, 26 Dec 2024 12:53:02 +0000 en-US hourly 1 https://blogs.perficient.com/files/favicon-194x194-1-150x150.png Vue.js Articles / Blogs / Perficient https://blogs.perficient.com/tag/vue-js/ 32 32 30508587 Dynamic Component Rendering in Vue.js: When and How to Use It https://blogs.perficient.com/2024/12/26/dynamic-component-rendering-in-vue-js-when-and-how-to-use-it/ https://blogs.perficient.com/2024/12/26/dynamic-component-rendering-in-vue-js-when-and-how-to-use-it/#respond Thu, 26 Dec 2024 12:51:50 +0000 https://blogs.perficient.com/?p=374449

Dynamic component rendering in Vue.js lets you display different components based on conditions at runtime. This feature is handy for building flexible, user-friendly, and scalable applications. Instead of hardcoding components into the layout, you can dynamically switch, or load components as needed.

What Is Dynamic Component Rendering?

Normally, components are fixed in the app’s layout. Dynamic component rendering changes this by allowing components to load based on certain conditions. Vue’s <component> tag makes this easy by binding the is attribute to a component name or configuration.

For example:

//Path: src/components/DynamicComponents/Simple.vue
<template>
    <component :is="currentComponent"></component>
</template>

Here, currentComponent decides which component is displayed. This approach is useful for switching tabs, showing conditional content, or reusing layouts.

When to Use Dynamic Component Rendering?

Dynamic component rendering is suited for scenarios where flexibility and reusability are priorities. Here are some common use cases:

  1. Conditional Displays: Replace multiple v-if conditions with dynamic components for a cleaner and simpler structure.
  2. Tabbed Interfaces: Use dynamic components to show only the active tab’s content in tabbed layouts.
  3. Reusable Sections: Load different headers, footers, or sidebars without duplicating code.
  4. Multi-Step Forms: Dynamically load components for each step in a workflow, improving performance and maintainability.
  5. Dashboards: Create customizable dashboards where widgets or modules are rendered dynamically based on user preferences.

How to Use Dynamic Component Rendering?

Dynamic component rendering in Vue.js revolves around the <component> element. This element dynamically switches the rendered component based on the value of the is attribute.

1) Switching Between Components

Let’s start with a basic example where a button click switches the rendered component.

Step 1: Define the Components

ComponentA.vue

//Path: src/components/DynamicComponents/ComponentA.vue
<template>
    <div>
      <h2>Component A</h2>
      <p>This is Component A. Welcome!</p>
    </div>
</template>
  
<script>
  export default {
    name: 'ComponentA',
  };
</script>

ComponentB.vue

//Path: src/components/DynamicComponents/ComponentB.vue
<template>
    <div>
      <h2>Component B</h2>
      <p>This is Component B. Welcome!</p>
    </div>
  </template>
  
  <script>
  export default {
    name: 'ComponentB',
  };
  </script>

Step 2: Main Application

Main.vue

//Path: src/components/DynamicComponents/Main.vue
<template>
  <div id="app">
    <h1>Dynamic Component Switching Example</h1>
    <div class="buttons">
      <!-- Buttons to Switch Components -->
      <button @click="currentComponent = 'ComponentA'">Show Component A</button>
      <button @click="currentComponent = 'ComponentB'">Show Component B</button>
    </div>
    <!-- Dynamic Component Rendering -->
    <component :is="currentComponent" class="dynamic-component"></component>
  </div>
</template>
<script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';
export default {
 components: {
 ComponentA, 
 ComponentB, 
},
  data() {
    return {
      currentComponent: 'ComponentA', // Default component to render
    };
  },
};
</script>

Output:

Img 20

How It Works

  1. Component Registration: ComponentA and ComponentB are imported into App.vue and registered in the components object.
  2. Dynamic Switching: The currentComponent data property controls which component is displayed.
    • Clicking “Show Component A” sets currentComponent to ‘ComponentA’.
    • Clicking “Show Component B” sets currentComponent to ‘ComponentB’.
  3. Dynamic Rendering: The <component> element dynamically renders the component specified by currentComponent.

2) Dynamic Tabs with Props

Dynamic components in Vue.js let you easily display different components based on user actions or changes in the app’s state. For example, in a tabbed interface, they allow you to switch between content views while keeping the code clean and organized. You can also make these components interactive by passing data to them using props. Imagine a dashboard with widgets like User Info, Notifications, and Tasks, where each widget is a separate component.

Step 1: Define the Components

Tab1.vue

//Path: src/components/DynamicComponents/Tab1.vue
<template>
  <div>
    <h3>Welcome to Tab 1</h3>
    <p>This is the content for Tab 1.</p>
  </div>
</template>
<script>
export default{
  name: 'Tab1',
  props: ['message']
}
</script>

Tab2.vue

//Path: src/components/DynamicComponents/Tab2.vue
<template>
  <div>
    <h3>Welcome to Tab 2</h3>
    <p>This is the content for Tab 2.</p>
  </div>
</template>
<script>
export default{
  name: 'Tab2',
  props: ['message']
}
</script>

Tab3.vue

//Path: src/components/DynamicComponents/Tab3.vue
<template>
  <div>
    <h3>Welcome to Tab 3</h3>
    <p>This is the content for Tab 3.</p>
  </div>
</template>
<script>
export default{
  name: 'Tab3',
  props: ['message']
}
</script>

Step 2: Main Application

App.vue

<template>
  <div id="app">
    <h1>Dynamic Tabs with Props Example</h1>
    <!-- Tab Navigation -->
    <div class="tab-buttons">
      <button v-for="tab in tabs" :key="tab.name" @click="currentTab = tab.component">
        {{ tab.name }}
      </button>
    </div>

    <!-- Dynamic Component Rendering -->
    <component :is="currentTab" v-bind="currentTabProps" class="dynamic-tab"></component>
  </div>
</template>
<script>
import Tab1 from './Tab1.vue';
import Tab2 from './Tab2.vue';
import Tab3 from './Tab3.vue';
export default {
 components: {
 Tab1, 
 Tab2, 
 Tab3, 
}, 
  data() {
    return {
      // Tabs configuration
      tabs: [
        { name: 'Tab 1', component: 'Tab1', props: { message: 'Hello from Tab 1!' } },
        { name: 'Tab 2', component: 'Tab2', props: { info: 'Data for Tab 2' } },
        { name: 'Tab 3', component: 'Tab3', props: { details: 'Details for Tab 3' } },
      ],
      currentTab: 'Tab1', // Default tab component
    };
  },
  computed: {
    // Find and provide the props for the current tab
    currentTabProps() {
      const tab = this.tabs.find(t => t.component === this.currentTab);
      return tab ? tab.props : {};
    },
  },
};
</script>

Output:

Img 9

How It Works

  1. Tabs Configuration: In App.vue, there is a tabs array that defines each tab’s name, associated component, and the props it will use.
  2. Dynamic Rendering: The <component> element is used to dynamically render the component for the currently selected tab (currentTab). Props are passed to the dynamic component using the v-bind directive.
  3. Switching Tabs: When a tab button is clicked, the currentTab value is updated. This triggers Vue to re-render the dynamic component for the selected tab.

3) Rendering Lists of Dynamic Components in Vue.js

In Vue.js, rendering a list of dynamic components is a useful feature, especially for things like dashboards or showing different types of widgets based on data. For example, you can create a dynamic dashboard with widgets like User Info, Notifications, and Tasks. Each widget is its own component, and they can be displayed dynamically based on the data provided.

Child Components

UserInfo.vue

<template>
    <div class="widget">
      <h3>User Info</h3>
      <p><strong>Name:</strong> {{ name }}</p>
      <p><strong>Email:</strong> {{ email }}</p>
    </div>
  </template>
  
  <script>
  export default {
    props: {
      name: String,
      email: String,
    },
  };
  </script>

Notification.vue

<template>
    <div class="widget">
      <h3>Notifications</h3>
      <ul>
        <li v-for="(notification, index) in notifications" :key="index">
          {{ notification }}
        </li>
      </ul>
    </div>
  </template>
  
  <script>
  export default {
    props: {
      notifications: Array,
    },
  };
  </script>

Task.vue

<template>
    <div class="widget">
      <h3>Tasks</h3>
      <ul>
        <li v-for="(task, index) in tasks" :key="index">
          {{ task }}
        </li>
      </ul>
    </div>
  </template>
  
  <script>
  export default {
    props: {
      tasks: Array,
    },
  };
  </script>

Parent Component:

App.vue

<template>
    <div id="app">
      <h1>Dynamic Dashboard</h1>
      <div class="dashboard">
        <!-- Render List of Dynamic Components -->
        <component
          v-for="(widget, index) in widgets"
          :is="widget.type"
          v-bind="widget.props"
          :key="index"
          class="dashboard-widget"
        ></component>
      </div>
    </div>
  </template>
  <script>
  import UserInfo from './UserInfo.vue';
  import Notifications from './Notification.vue';
  import Tasks from './Tasks.vue';
  export default {
  components: {
  UserInfo, 
  Notifications, 
  Tasks, 
  },
    data() {
      return {
        // List of widgets to render dynamically
        widgets: [
          {
            type: 'UserInfo',
            props: {
              name: 'ABC ',
              email: 'abc.xyz@example.com',
            },
          },
          {
            type: 'Notifications',
            props: {
              notifications: [
                'New comment on your post',
                'Your profile has been updated',
              ],
            },
          },
          {
            type: 'Tasks',
            props: {
              tasks: ['Complete the Vue.js tutorial', 'Update the project plan', 'Fix the login bug'],
            },
          },
        ],
      };
    },
  };
  </script>

Output:

Img 11

How It Works

  1. Dynamic Components: The <component> element dynamically renders a component specified by the type of property in the widgets array.
  2. Widgets Array: Each object in the widgets array contains:
    • type: The name of the component to render (e.g., ‘UserInfo’).
    • props: The data to pass to the component as props.
  3. Reusability
    • Each widget is a self-contained component with its own logic and props, making it reusable.
  4. Data-Driven UI
    • Adding, removing, or modifying widgets is as simple as updating the widgets array in the parent component.

4) Lazy Loading Dynamic Components

Lazy loading dynamic components helps improve performance by loading components only when they are needed. In Vue.js, you can use asynchronous functions to lazy-load components, making large apps with many components load faster.

Child Components

Tab1.vue

<template>
  <div>
    <h3>Welcome to Tab 1</h3>
    <p>This is the content for Tab 1.</p>
  </div>
</template>
<script>
export default{
  name: 'Tab1',
  props: ['message']
}
</script>

Tab2.vue

<template>
  <div>
    <h3>Welcome to Tab 2</h3>
    <p>This is the content for Tab 2.</p>
  </div>
</template>
<script>
export default{
  name: 'Tab2',
  props: ['message']
}
</script>

Tab3.vue

<template>
  <div>
    <h3>Welcome to Tab 3</h3>
    <p>This is the content for Tab 3.</p>
  </div>
</template>
<script>
export default{
  name: 'Tab3',
  props: ['message']
}
</script>

Parent Component:

App.vue

<template>
  <div id="app">
    <h1>Lazy Loading Dynamic Components</h1>
    <!-- Buttons to Load Components -->
    <div class="tab-buttons">
      <button v-for="tab in tabs" :key="tab.name" @click="loadTab(tab.component)">
        {{ tab.name }}
      </button>
    </div>
    <!-- Lazy-Loaded Dynamic Component -->
    <component v-if="currentTab" :is="currentTab" class="dynamic-tab"></component>
  </div>
</template>

<script>
import { markRaw } from 'vue';

export default {
  data() {
    return {
      // Configuration for dynamic components
      tabs: [
        { name: 'Tab 1', component: () => import('./Tab1.vue') },
        { name: 'Tab 2', component: () => import('./Tab2.vue') },
        { name: 'Tab 3', component: () => import('./Tab3.vue') },
      ],
      currentTab: null, // Initially no tab is loaded
    };
  },
  methods: {
    async loadTab(componentLoader) {
      // Resolve the module and mark it as raw
      const resolvedComponent = await componentLoader();
      this.currentTab = markRaw(resolvedComponent.default);
    },
  },
};
</script>

<style>
#app {
  font-family: Arial, sans-serif;
  max-width: 600px;
  margin: 50px auto;
  text-align: center;
}

.tab-buttons {
  margin-bottom: 20px;
}

button {
  padding: 10px 15px;
  margin: 0 5px;
  border: none;
  background-color: #007bff;
  color: white;
  font-size: 16px;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background-color: #0056b3;
}

.dynamic-tab {
  margin-top: 20px;
  padding: 20px;
  border: 1px solid #ddd;
  border-radius: 8px;
  background: #f9f9f9;
}
</style>

Output:

Img 8

Conclusion

Dynamic component rendering in Vue.js is a powerful feature for building flexible and modern apps. It lets developers show components based on conditions, switch layouts, and improve workflows, leading to cleaner and more scalable code. Whether you’re making a multi-step form, a tabbed interface, or a customizable dashboard, learning to use dynamic components will enhance your Vue.js skills.

]]>
https://blogs.perficient.com/2024/12/26/dynamic-component-rendering-in-vue-js-when-and-how-to-use-it/feed/ 0 374449
How to Use Vue.js Transitions for Smooth UI Animations https://blogs.perficient.com/2024/12/26/how-to-use-vue-js-transitions-for-smooth-ui-animations/ https://blogs.perficient.com/2024/12/26/how-to-use-vue-js-transitions-for-smooth-ui-animations/#respond Thu, 26 Dec 2024 07:34:58 +0000 https://blogs.perficient.com/?p=372773

Animations aren’t just for show—they’re key to making web apps more engaging and user-friendly. In this guide, we’ll explore how to easily add smooth transitions and animations to your Vue.js apps. Whether it’s simple effects or advanced animations with libraries like GSAP, Vue makes it easy to bring your UI to life. Let’s dive in!

Why Use Animations in Web Apps?

Animations improve how users interact with your app by making it feel smoother and more intuitive. Here’s how:

  • Better Navigation: Smooth transitions between pages or sections help users follow the flow of the app easily.
  • More Polished Experience: Simple animations, like hover effects or button presses, make your app feel more responsive and professional.
  • Clear Feedback: Animations can show users when something is loading, when there’s an error, or when an action is successful, making it easier for users to understand what’s happening.

Animations in Vue.js

Vue.js offers built-in support for both transitions and animations, making it easy to enhance the user interface. These features are primarily handled by the <transition> and <transition-group> components:

  • Transitions: Use <transition> to apply animations or effects to a single element or component as it enters, leaves, or changes state.
  • Animations: Use <transition-group> for list-based animations, such as adding, removing, or reordering items in a list.

These components provide powerful tools to control animations and transitions in a smooth, efficient way.

  1. The <transition> Component

The <transition> component in Vue.js allows you to apply animations or transitions to elements when they are added, updated, or removed from the DOM. It provides an easy way to control the appearance and disappearance of elements with smooth effects.

<template>
    <div>
      <button @click="toggle">Toggle</button>
      <transition name="fade">
        <p v-if="show">Hello, Vue.js Animations!</p>
      </transition>
    </div>
  </template>
  
  <script>
  export default {
    data() {
      return {
        show: false,
      };
    },
    methods: {
      toggle() {
        this.show = !this.show;
      },
    },
  };
  </script>
  
  <style>
  .fade-enter-active, .fade-leave-active {
    transition: opacity 0.5s;
  }
  .fade-enter-from, .fade-leave-to {
    opacity: 0;
  }
  </style>

Output:

Img 1

In this example:

  • fade-enter-active: Controls the transition when the element is entering (appearing).
  • fade-leave-active: Controls the transition when the element is leaving (disappearing).
  • fade-enter-from and fade-leave-to: Define the initial and final states.
  1. Animating Lists with <transition-group>

When you need to animate multiple elements, such as a list, Vue.js provides the <transition-group> component. It allows you to apply transitions or animations to each item in a list when they are added, removed, or reordered. The <transition-group> component is especially useful when you have dynamic lists, and you want to animate changes like adding, removing, or reordering items.

<template>
    <div>
      <button @click="addItem">Add Item</button>
      <transition-group name="list" tag="ul">
        <li v-for="(item, index) in items" :key="index">{{ item }}</li>
      </transition-group>
    </div>
  </template>  
  <script>
  export default {
    data() {
      return {
        items: ['Item 1', 'Item 2', 'Item 3'],
      };
    },
    methods: {
      addItem() {
        this.items.push(`Item ${this.items.length + 1}`);
      },
    },
  };
  </script>

Output:

Img 2

Here, <transition-group> automatically applies animation classes to each list item as they enter or leave the DOM.

  1. JavaScript Hooks for Custom Animations

While CSS transitions are good for basic animations, sometimes you need more control. Vue.js lets you use JavaScript hooks to create custom animations. These hooks give you more control over the animation, letting you create complex effects that CSS alone can’t do.

<template>
    <div>
      <button @click="toggle">Toggle Box</button>
      <transition
        @before-enter="beforeEnter"
        @enter="enter"
        @leave="leave"
      >
      <div v-if="show" class="box"></div>
      </transition>
    </div>
  </template>
  <script>
  export default {
    data() {
      return {
        show: false,
      };
    },
    methods: {
      toggle() {
        this.show = !this.show;
      },
      beforeEnter(el) {
        el.style.opacity = 0;
      },
      enter(el, done) {
        el.style.transition = 'opacity 0.5s';
        setTimeout(() => {
          el.style.opacity = 1;
          done();
        }, 50);
      },
      leave(el, done) {
        el.style.transition = 'opacity 0.5s';
        el.style.opacity = 0;
        setTimeout(done, 500);
      },
    },
  };
  </script>

Output:

Img 3

This code uses Vue’s <transition> component with JavaScript hooks to create a fade-in and fade-out animation for a box. When the button is clicked, the show property controls whether the box is visible or not.

  • beforeEnter sets the box’s opacity to 0 (invisible).
  • enter gradually increases the opacity to 1 (fully visible) over 0.5 seconds.
  • leave fades the opacity back to 0 (invisible) in the same duration.

The transitions are smooth, and the done() function ensures the timing is correct.

  1. Integrating Third-Party Libraries

For more complex animations, third-party libraries like Animate.css or GSAP are great options.

Using Animate.css

Animate.css is a popular CSS library that offers ready-made animations like fade, bounce, zoom, and slide. Developers can easily apply these animations to web elements by adding specific CSS classes, without needing custom JavaScript or CSS. It’s lightweight, simple to use, and works well with frameworks like Vue.js to improve the user interface.

Img 6

<template>
    <div>
      <button @click="toggle">Toggle Animation</button>
      <transition
        enter-active-class="animate__animated animate__fadeIn"
        leave-active-class="animate__animated animate__fadeOut">
        <p v-if="show">Hello, Animated World!</p>
      </transition>
    </div>
  </template>  
  <script>
  export default {
    data() {
      return {
        show: false,
      };
    },
    methods: {
      toggle() {
        this.show = !this.show;
      },
    },
  };
  </script>
<style>
@import 'animate.css';
</style>

Output:

Img 4

In the example, Animate.css is used with Vue’s <transition> component to add fade-in and fade-out effects to a paragraph. The toggle method controls the visibility of the paragraph by toggling the show property, while the pre-defined Animate.css classes handle the animations.

Advanced Animations with GSAP

GSAP (GreenSock Animation Platform) is a powerful JavaScript library for creating smooth, high-quality animations. It allows you to animate DOM elements, SVGs, and canvas with advanced features like timelines and sequencing. With its easy-to-use API and plugins, GSAP helps you build interactive, eye-catching websites with more complex animations than basic effects.

Img 7

<template>
<div>
<button @click="toggle">Toggle GSAP Animation</button>
<transition
>
@enter-"enter" @Leave="leave
<div v-if-"show" class="gsap-box"></div> </transition>
</div>
</template>
<script>
import {gsap } from 'gsap';
export default {
data()
{
return {
show: false,
};
},
methods: {
toggle() {
};
},
},
this show this.show;
enter(el, done) (
},
gsap.fromTo(el) { opacity: 0, y: -58 }, { opacity: 1, y: 0, duration: 8.5, onComplete: done });
leave(el, done) {
},
gsap.to(el, { opacity: 0, y: 50, duration: 0.5, onComplete: done });
</script>
<style>
.gsap-box{
 width: 100px;
 height: 100px;
 background-color: green;
}
</style>

Output:

Img 5

In this example, we use GSAP (GreenSock Animation Platform) to animate a box. When the “Toggle GSAP Animation” button is clicked, the box smoothly fades in while sliding up and fades out while sliding down when it is hidden.

Best Practices for Animations:

  1. Keep Animations Subtle: Keep animations simple so they don’t distract users from the main content.
  2. Optimize Performance: Use CSS properties like transform and opacity to keep animations smooth and quick.
  3. Fallbacks for Accessibility: Let users turn off animations if they prefer less movement, making your app more accessible.
  4. Test on All Devices: Check that your animations work well on both powerful computers and less powerful phones to ensure smooth performance everywhere.

Conclusion

With Vue.js, adding animations to your web apps has never been easier. Whether you’re looking to add simple effects like fading in and out or dive into more complex animations with powerful libraries like GSAP, Vue gives you the flexibility to enhance your app’s user experience. Make your app more interactive and fun to use—start experimenting with animations today and make your projects stand out! From basic transitions to advanced effects, Vue has all the tools you need to bring your ideas to life.

]]>
https://blogs.perficient.com/2024/12/26/how-to-use-vue-js-transitions-for-smooth-ui-animations/feed/ 0 372773
Understanding Lifecycle Methods in Vue.js https://blogs.perficient.com/2024/12/20/lifecycle-methods-in-vue-js/ https://blogs.perficient.com/2024/12/20/lifecycle-methods-in-vue-js/#respond Fri, 20 Dec 2024 08:51:39 +0000 https://blogs.perficient.com/?p=372652

People praise Vue.js as a powerful and flexible JavaScript framework for its simplicity and ease of use. Vue.js includes lifecycle hooks as one of its standout features. These hooks allow developers to execute specific actions at various stages of a component’s life, making it easier to manage complex logic and interactions. In this guide, we’ll explore these lifecycle hooks and show how you can leverage them to create more efficient and responsive Vue.js applications.

What Are Lifecycle Hooks?

Every Vue component goes through a lifecycle, from its creation and updates to its eventual removal from the DOM. Vue lifecycle hooks are built-in methods that allow you to “hook” into different stages of this lifecycle, so you can run custom logic at the right moment.

Lifecycle hooks are divided into four main stages:

  1. Creation
  2. Mounting
  3. Updating
  4. Destruction

Let’s dive into each of these stages to understand how they work.

1) Creation Hooks:

Kickstart Your Vue Component: Creation Hooks Explained

Creation hooks are triggered when a component is first created, but before it is added to the DOM. This stage is useful for setting default values, initializing data, or making initial API requests.

beforeCreate()

  • Purpose: This hook is called immediately after the Vue instance is created, but before any data or styles are set up.
  • Use Case: This hook is typically used for initializing basic operations, such as setting up a loading state or preparing some default properties.

created()

  • Purpose: This hook is called after the Vue instance has been created, and the component’s data, computed properties, and methods are now accessible.
  • Use Case: A great place for fetching data from an API or setting initial component data.

Example: Fetching user data when the component is created

<template>
    <div>
      <h2>User Profile</h2>
      <div v-if="loading">Loading user data...</div>
      <div v-else-if="error">{{ error }}</div>
      <div v-else>
        <p><strong>Name:</strong> {{ userData.firstName }} {{ userData.lastName }}</p>
        <p><strong>Email:</strong> {{ userData.email }}</p>
        <p><strong>Image:</strong></p>
        <img :src="userData.image" alt="User Image" />
      </div>
    </div>
  </template>
  
  <script>
  export default {
    data() {
      return {
        userData: null,    // Will hold a single user's data after fetching
        loading: true,     // Used to show loading state
        error: null        // Used to show error messages if the API call fails
      };
    },
    beforeCreate() {
      console.log("Component is initializing...");
    },
    created() {
      console.log("Component has been created, data and methods are accessible now.");
      this.fetchUserData(); // Fetch data when component is created
    },
    methods: {
      async fetchUserData() {
        try {
          // API request to fetch user data
          const response = await fetch("https://dummyjson.com/users");
          if (!response.ok) throw new Error("Failed to fetch user data");
          const data = await response.json(); // Get the response as JSON
          this.userData = data.users[0]; // Assign the first user in the array to `userData`
        } catch (error) {
          this.error = "An error occurred while fetching user data.";
          console.error(error); // Log the error for debugging
        } finally {
          this.loading = false; // Stop showing the loading indicator
        }
      }
    }
  };
  </script>

Output:

Img 1

Explanation:

In this example, the created() hook triggers the data-fetching process, and the component’s state is updated accordingly. It first shows a loading message, and then either the user’s data or an error message is displayed.

2) Mounting Hooks

Smooth DOM Integration with Mounting Hooks

Mounting hooks are triggered when a component is added to the DOM. This is the ideal time to perform DOM-related tasks, as the component is fully initialized at this point.

beforeMount()

  • Purpose: Called before the component is mounted to the DOM, but after the render function has been prepared.
  • Use Case: Useful for setup tasks right before the DOM is rendered (e.g., adjusting styles or preparing data), but it’s less commonly used in practice.

mounted()

  • Purpose: Called after the component is mounted to the DOM. This is the best time to interact with the DOM, set up third-party libraries, or add event listeners.
  • Use Case: Frequently used for tasks like DOM manipulation or setting up event listeners.

Example: Fetching user data when the component is mounted

<template>
    <div>
      <h2>User Profile</h2>
      <div v-if="loading">Loading user data...</div>
      <div v-else-if="error">{{ error }}</div>
      <div v-else>
        <p><strong>Name:</strong> {{ userData.firstName }} {{ userData.lastName }}</p>
        <p><strong>Email:</strong> {{ userData.email }}</p>
        <p><strong>Image:</strong></p>
        <img :src="userData.image" alt="User Image" />
      </div>
    </div>
  </template>
  <script>
  export default {
    data() {
      return {
        userData: null,    // Will hold user data after fetching
        loading: true,     // Used to show loading state
        error: null        // Used to show error messages if the API call fails
      };
    },  
    beforeMount() {
      console.log("Component is about to mount...");
      // Useful for pre-mount setup (e.g., adjusting DOM, preparing data)
    },
     mounted() {
      console.log("Component has been mounted to the DOM!");
      // Ideal for interacting with the DOM, like setting focus or event listeners
      this.fetchUserData(); // Call fetch data when component is mounted
    },  
    methods: {
      async fetchUserData() {
        try {
          const response = await fetch("https://dummyjson.com/users");
          if (!response.ok) throw new Error("Failed to fetch user data");
          const data = await response.json();
          this.userData = data.users[0]; // Set the first user in the list
        } catch (error) {
          this.error = "An error occurred while fetching user data.";
          console.error(error);
        } finally {
          this.loading = false;
        }
      }
    }
  };
  </script>

Output:

Img 2

Explanation:

The mounted() hook handles data fetching here. Vue loads the user data only after mounting the component, making this the ideal time to interact with the DOM.

3) Updating Hooks

Managing Data Changes: Mastering Updating Hooks

Updating hooks are triggered whenever reactive data changes, causing the component to re-render. These hooks allow you to monitor and react to these changes.

beforeUpdate()

  • Purpose: Invoked just before the DOM is about to update due to a reactive data change.
  • Use Case: Can be used for preparation tasks, such as logging data changes or making minor UI adjustments before the update.

updated()

  • Purpose: Called right after the DOM update occurs.
  • Use Case: Useful for tasks that rely on the updated DOM, such as triggering animations or interacting with third-party libraries.

Example: Updating data and tracking changes

<template>
    <div>
      <h2>Counter Example with Updating Hooks</h2>
      <p>Counter Value: {{ counter }}</p>
      <button @click="incrementCounter">Increment Counter</button>
      <p>{{ message }}</p>
    </div>
  </template>
  <script>
  export default {
    data() {
      return {
        counter: 0,    // Counter that will be incremented
        message: ""    // Message to display after updating
      };
    },
    beforeUpdate() {
      console.log("Component is about to re-render...");
      this.message = "Updating counter...";
      // This hook can be used to perform any preparation or clean-up just before the update happens.
    },
    updated() {
      console.log("Component has re-rendered!");
      this.message = "Counter updated successfully!";
    },
    methods: {
      incrementCounter() {
        this.counter += 1; // Increment the counter, triggering the update lifecycle hooks
      }
    }
  };
  </script>

Output:

Img 3

Explanation:

Clicking the button triggers both beforeUpdate() and updated(), allowing you to manage the component’s state before and after the update.

4) Destruction Hooks

Cleaning Up After Your Component: Destruction Hooks

Destruction hooks are triggered before a component is removed from the DOM. This stage is essential for cleaning up resources like timers or event listeners.

beforeUnmount()

  • Purpose: Called just before the component instance is destroyed.
  • Use Case: Used for cleaning up things like event listeners or clearing intervals.

unmounted()

  • Purpose: Called after the component is destroyed and removed from the DOM.
  • Use Case: Final cleanup tasks, such as removing global event listeners or stopping ongoing processes.

Example: Cleaning up after a timer

<template>
    <div>
      <h2>Timer Component</h2>
      <p>Elapsed Time: {{ seconds }} seconds</p>
      <button @click="toggleTimer">Toggle Timer</button>
    </div>
  </template>
  
  <script>
  export default {
    data() {
      return {
        seconds: 0,     // Keeps track of elapsed time
        timer: null     // Stores the timer reference
      };
    },
    mounted() {
      console.log("Component mounted, starting timer...");
      this.startTimer(); // Start timer when component is mounted
    },
    beforeUnmount() {
      console.log("Component is about to be unmounted, clearing timer...");
      clearInterval(this.timer); // Clear timer before unmounting
    },
    unmounted() {
      console.log("Component has been unmounted!");
      // Any additional cleanup can be performed here
    },
  
    methods: {
      startTimer() {
        this.timer = setInterval(() => {
          this.seconds += 1; // Increment seconds every second
        }, 1000);
      },
      stopTimer() {
        clearInterval(this.timer); // Stop the timer
        this.timer = null;
      },
      toggleTimer() {
        if (this.timer) {
          this.stopTimer();
        } else {
          this.startTimer();
        }
      }
    }
  };
  </script>

Output:

Img 4

Explanation:

In this example, the timer is started when the component is mounted, and stopped when it’s about to be unmounted, ensuring no memory leaks.

Conclusion:

Lifecycle hooks in Vue.js offer a powerful way to control and manage the lifecycle of components. By understanding when and how to use these hooks—whether for initialization, data updates, or cleanup—you can significantly improve the performance and maintainability of your Vue applications.

By leveraging the creation, mounting, updating, and destruction stages, you can optimize your app’s behavior, create seamless user interactions, and avoid common pitfalls like memory leaks or inefficient DOM updates.

Mastering lifecycle hooks will deepen your understanding of Vue.js and enable you to write more responsive and efficient applications.

These revisions enhance clarity, consistency, and flow while reinforcing the core concepts of Vue.js lifecycle hooks.

]]>
https://blogs.perficient.com/2024/12/20/lifecycle-methods-in-vue-js/feed/ 0 372652
Setting Up Tailwind CSS with Theme Files and Images in Vue.js https://blogs.perficient.com/2024/12/20/setting-up-tailwind-css-with-theme-files-and-images-in-vue-js/ https://blogs.perficient.com/2024/12/20/setting-up-tailwind-css-with-theme-files-and-images-in-vue-js/#respond Fri, 20 Dec 2024 08:04:36 +0000 https://blogs.perficient.com/?p=372725

What is Tailwind CSS?

Tailwind CSS is a utility-first CSS framework that makes styling easier by offering pre-built utility classes. These classes let developers quickly create responsive and modern designs. When used with Vue.js, a progressive JavaScript framework, it provides an efficient setup for building complex web apps. This guide will show you how to set up Tailwind CSS in a Vue.js project, create theme files for customization, and manage images properly.

Step 1: Setting Up a Vue.js Project

Before starting, ensure that Node.js and npm are installed on your system.

Using Vue CLI

  1. Install Vue CLI globally:
    npm install -g @vue/cli

    Img 1

  2. Create a new project:
    vue create my-vue-tailwind-css-project

    Img 2

  3. Navigate to the project directory:
    cd my-vue-tailwind-css-project

    Img 3

Step 2: Installing Tailwind CSS

Tailwind CSS must be added to your project, along with its dependencies.

  1. Install Tailwind CSS, PostCSS, and Autoprefixer:
    npm install -D tailwindcss postcss autoprefixer

    Img 4
    Note: PostCSS is a tool that uses plugins to optimize and improve CSS styles, whereas Autoprefixer inserts browser-specific prefixes to ensure compatibility with older browsers. Tailwind CSS makes advantage of both to ensure seamless development and cross-browser support.

  2. Initialize Tailwind CSS:

    npx tailwindcss init

    Img 5
    Note: This command generates a tailwind.config.js file for configuration.

Step 3: Configuring Tailwind CSS

To make Tailwind CSS functional in your project:

  1. Open tailwind.config.js and specify the files Tailwind should scan for class names:
    //Path: tailwind.config.js
    /** @type {import('tailwindcss').Config} */
    module.exports = {
      content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
      theme: {
        extend: {
        },
      },
      plugins: [],
    }
  2. Create a Tailwind CSS file (e.g., src/assets/tailwind.css) and include Tailwind’s base, component, and utility styles:
    //Path: tailwind.css
    @tailwind base;
    @tailwind components;
    @tailwind utilities;
  3. Import this CSS file in your main JavaScript file (main.js or main.ts):
    //Path: main.js
    { createApp } from 'vue'
    import App from './App.vue'
    import './assets/tailwind.css';
    createApp(App).mount('#app')

Step 4: Adding Theme Files for Customization

A key feature of Tailwind CSS is its ability to extend the default design system with custom themes.

Customize Colors and Fonts

Modify tailwind.config.js to define your brand-specific colors and fonts:

//Path: tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
  theme: {
    extend: {
      colors: {
        primary: '#1D4ED8',  // Primary color
        secondary: '#9333EA', // Secondary color
      },
      fontFamily: {
        sans: ['Inter', 'sans-serif'], // Custom font
      },
      backgroundImage: {
        'hero-pattern': "url('@/assets/Background_image.png')",
      },
    },
  },
  plugins: [],
}

Usage in Vue Components

Use the defined classes directly in your components:

//Path: HelloWorld.vue
<template>
  <div class="bg-black text-white font-sans p-4">
    Welcome to Tailwind CSS in Vue Js Project!
  </div>
</template>

<script>
export default{
  name: 'HelloWorld'
}
</script>

Output:

Img 10

Step 5: Managing Images in Vue.js

Most web apps include images. Proper handling guarantees improved performance and maintainability.

Adding Images

Place all your images in the src/assets directory.

Img 8

Using Images in Vue Templates

Reference images using relative paths:

//Path: HelloWorld.vue
<template>
  <div>
    <!-- Welcome section -->
    <div class="bg-black text-white font-sans p-4">
      Welcome to Tailwind CSS in Vue.js Project!
    </div>

    <!-- Image section with a centered image -->
    <div class="p-4">
      <img :src="require('@/assets/Background_image.png')" alt="Background Image" class="rounded-lg shadow-lg w-full max-w-[600px] mx-auto" />
    </div>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
};
</script>

<style scoped>
/* Optional: Styling for the image */
img {
  width: 100%;
  max-width: 600px;
}
</style>

Output:

Img 12

Using Images as Backgrounds

To use images as background properties, update tailwind.config.js:

// Path: tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
  theme: {
    extend: {
      colors: {
        secondary: '#9333EA', // Custom secondary color
      },
      fontFamily: {
        sans: ['Inter', 'sans-serif'], // Custom sans-serif font
      },
      backgroundImage: {
        'hero-pattern': "url('@/assets/logo.jpg')", // Set custom background image
      },
    },
  },
  plugins: [],
}

Apply the custom background in your component:

// Path: HelloWorld.vue
<template>
  <div>
    <!-- First div with background color and styling -->
    <div class="bg-indigo-500 text-white font-sans p-4">
      Welcome to Tailwind CSS in Vue.js Project!
    </div>

    <!-- Second div with the custom background image applied -->
    <div class="bg-hero-pattern bg-contain bg-center bg-no-repeat h-64 w-full">
      <!-- Content for this section (if any) can go here -->
    </div>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
};
</script>

<style scoped>
/* The background image is already applied via Tailwind's bg-hero-pattern class.
   No need to redefine it here. If you want additional styles, add them below. */

/* Optional styles for the section could go here. */
</style>

Output:

Img 11

Conclusion

Tailwind CSS and Vue.js are an effective mix for creating modern, responsive, and maintainable applications. You can develop visually attractive UIs tailored to the needs of your project by configuring a custom theme and effectively managing pictures.

]]>
https://blogs.perficient.com/2024/12/20/setting-up-tailwind-css-with-theme-files-and-images-in-vue-js/feed/ 0 372725
Understanding Custom Events in Vue.js https://blogs.perficient.com/2024/12/03/how-to-simplify-component-communication-in-vue-js-using-custom-events/ https://blogs.perficient.com/2024/12/03/how-to-simplify-component-communication-in-vue-js-using-custom-events/#comments Tue, 03 Dec 2024 13:47:43 +0000 https://blogs.perficient.com/?p=371919

Are You Struggling with Component Communication in Vue.js?

Building dynamic, maintainable applications in Vue.js requires seamless communication between components. But how can you ensure that your child components communicate effectively with their parent components—without creating a tangled mess of props, state management, and confusing logic?

Custom events in Vue.js offer a clean, simple, and powerful way to solve this problem, allowing your app to stay flexible, scalable, and easy to maintain. In this guide, we’ll walk through how to use custom events with Vue’s Options API to effortlessly pass data, trigger actions, and keep your components decoupled.

What Are Custom Events in Vue.js?

Custom events enable child components to send messages or data to their parent components. This is crucial when a child needs to:

  • Notify the parent about a change in state
  • Trigger actions or methods in the parent
  • Pass data back to the parent, such as user input or updates

Vue.js makes it simple to emit events from a child component and listen for those events in the parent, ensuring smooth communication between the two.

Why Should You Use Custom Events?

Custom events bring several key advantages to your Vue.js application:

  • Send Data to Parent Components: Easily emit data or updates from the child to the parent.
  • Trigger Parent Actions: Call parent methods or trigger actions from the child component.
  • Maintain Loose Coupling: Custom events allow you to keep components independent of each other, making your app easier to scale and maintain.

How to Emit Custom Events with this.$emit()

In Vue.js, the ‘this.$emit()’ method is used to trigger custom events from a child component to its parent. This allows the child to communicate with the parent, notifying it of actions like user interactions or state changes.

Syntax: this.$emit(‘event-name’, payload);

  • event-name: The name of the custom event to emit.
  • payload (optional): The data you want to pass with the event (could be a string, object, number, etc.).

Let’s walk through a practical example to see how custom events work.

Step-by-Step Guide to Emitting Custom Events in Vue.js

Example1: Emitting Custom Events with Arguments

Scenario: Task Management System

Child Component: (AddTask.vue)

Allows the user to add a new task to the list.

<template>
  <div>
    <input v-model="taskText" placeholder="Enter task" />
    <button @click="submitTask">Add Task</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      taskText: ''
    };
  },
  methods: {
    submitTask() {
      this.$emit('add-task', this.taskText);  // Emitting custom event with task text
    }
  }
}
</script>

Parent Component: (App.vue)

Manages a list of tasks and displays them.

<template>
  <div>
    <h1>Task List</h1>
    <AddTask @add-task="addTask" />
    <ul>
      <li v-for="task in tasks" :key="task.id">{{ task.id }} - {{ task.text }}</li>
    </ul>
  </div>
</template>

<script>
import AddTask from './AddTask.vue';

export default {
  components: {
    AddTask
  },
  data() {
    return {
      tasks: [],
      taskId: 1
    };
  },
  methods: {
    addTask(newTaskText) {
      this.tasks.push({
        id: this.taskId,
        text: newTaskText
      });
      this.taskId++;
    }
  }
}
</script>

Output:

Enter ‘Task One’ in the input box and click the ‘Add Task’ button to add the task.

Img 1

How it works:

In the Child Component (AddTask.vue):

  • We listen for the click event on the button and trigger the submitTask method.
  • Inside submitTask(), we use this.$emit(‘add-task’, this.taskText) to emit the custom event add-task with the entered task text as the data.

In the Parent Component (App.vue):

  • The parent listens for the add-task event using @add-task=”addTask”.
  • The addTask() method receives the task text as an argument, processes it, and adds it to the tasks array.

Example2: Emitting Custom Events with Object

Now, let’s look at a more complex example, where the child emits an object with user data, and the parent processes that data.

Scenario: Displaying User Information.

Child Component: (UserInfo.vue)

Contains user information and emits it as an object.

<template>
  <div>
    <button @click="sendUserData">Send User Info</button>
  </div>
</template>

<script>
export default {
  methods: {
    sendUserData() {
      const userData = { name: 'John Doe', age: 30 };
      this.$emit('user-data', userData);  // Emitting object with user data
    }
  }
}
</script>

Parent Component: (App.vue)

Listens for the user data and processes it.

<template>
  <div>
    <h1>User Information</h1>
    <UserInfo @user-data="handleUserData" />
    <p>Name: {{ userInfo.name }} </p>
    <p>Age{{ userInfo.age }}</p>
  </div>
</template>

<script>
import UserInfo from './UserInfo.vue';

export default {
  components: {
    UserInfo
  },
  data() {
    return {
      userInfo: {}
    };
  },
  methods: {
    handleUserData(userData) {
      this.userInfo = userData;  // Receiving and storing the user data
    }
  }
}
</script>

Output:

Click the button to view user information

Img 4

How It Works:

  1. In the Child Component (UserInfo.vue):
    • We emit an event with an object containing name and age as data.
  2. In the Parent Component (App.vue):
    • The parent listens for the event, receives the object, and logs or displays the user data.

Event Modifiers in Vue.js

Vue provides powerful event modifiers that give you greater control over custom events. For example:

  • .once: Fires the event listener only once.
  • .stop: Stops the event from propagating further.
  • .prevent: Prevents the default behavior of the event.
  • .capture: Listens during the capturing phase.

Here’s how to use them:

<ChildComponent @message-sent.once=”handleMessage” />

Conclusion: 

Custom events in Vue.js allow child components to communicate with their parents, making it easier to pass data, trigger actions, and maintain loose coupling between components. By understanding how to use this.$emit(), handle data passing, and utilize event modifiers, you can keep your Vue.js applications clean, maintainable, and scalable.

]]>
https://blogs.perficient.com/2024/12/03/how-to-simplify-component-communication-in-vue-js-using-custom-events/feed/ 2 371919
Understanding data(), Interpolation and Computed Properties in Vue.js https://blogs.perficient.com/2024/12/03/vuejs-data-interpolation-method-computed-properties/ https://blogs.perficient.com/2024/12/03/vuejs-data-interpolation-method-computed-properties/#respond Tue, 03 Dec 2024 13:46:46 +0000 https://blogs.perficient.com/?p=372037

How to Easily Manage and Display Data in Vue.js?

Are you building a dynamic, interactive Vue.js app and wondering how to manage and display data efficiently? In this guide, we’ll show you how to easily store data, display it instantly on your page with Vue’s interpolation, and optimize complex calculations with computed properties. These features will help your app run faster and smoother than ever!

What is data()?

  • The data() function in Vue is used to define the initial reactive state of a component.
  • The properties returned by data() can include various types of values, such as strings, numbers, arrays, or objects.

Key Points:

  1. Reactivity: When you define a property inside the data() function, Vue automatically tracks changes to that property. Whenever the data changes, Vue updates the DOM automatically to reflect the new values.
  2. Data Types: The data() function can return any type of data (strings, numbers, arrays, objects), and those types will be reactively linked to your template.

How to Use data()

The data() function must return an object, where each property is reactive. This means any change to the properties will trigger automatic DOM updates.

Syntax:

<script>
export default {
data() {
return {
// Define your properties here
};
}
};
</script>

Example:

<script>
export default {
data() {
return {
message: "Welcome to Vue!",
name: "John",
count: 0
};
}
};
</script>

In this example, three properties—message, name, and count—are defined in the data() function. Whenever these properties change, Vue automatically updates the view to reflect the new values.

Interpolation

Interpolation in Vue.js is the process of injecting dynamic content into your template. It allows you to display data defined in your data() function (or computed properties) directly within the HTML, using double curly braces: {{ }}.

Purpose:

Dynamic Content: Interpolation is used to display dynamic data, such as user names, messages, numbers, etc. It eliminates the need to manually update the DOM whenever the data changes.

Syntax:

<p>{{ message }}</p>

Example:

<template>
<div>
<p>{{ message }}</p>
<p>{{ name }}</p>
<p>{{ count }}</p>
<button @click="incrementCount">Increment Count</button>
</div>
</template>
  • {{ message }} displays the value of the message property (“Welcome to Vue!”).
  • {{ name }} displays the value of name (“John”).
  • {{ count }} displays the value of count (0).

When the component renders, Vue automatically replaces the interpolation tags ({{ message }}, {{ name }}, etc.) with their corresponding values. If any data property changes (e.g., count is incremented), Vue updates the DOM without requiring manual intervention.

What Are Methods in Vue.js?

In Vue.js, methods are functions that are used to handle events or actions triggered by the user, such as clicks, form submissions, or other interactions. Unlike computed properties, methods are not cached and will re-run every time they are called.

How to Use Methods

Methods are defined in the methods section of a Vue component and can be invoked in response to events.

Syntax:

<script>
export default {
methods: {
methodName() {
// Your logic here
}
}
};
</script>

Example:

<template>
<div>
<p>{{ message }}</p>
<p>{{ name }}</p>
<p>{{ count }}</p>
<button @click="incrementCount">Increment Count</button>
</div>
</template>

<script>
export default {
data() {
return {
message: "Welcome to Vue!",
name: "John",
count: 0
};
},
methods: {
incrementCount() {
this.count++;
}
}
};
</script>

In this example, the incrementCount method is triggered when the button is clicked. It increments the count property, which automatically updates the view.

Output:

Before clicking the button: count = 0

Img 3 After clicking the button: count = 1

Img 4


Computed

Computed properties in Vue.js are special, reactive properties that are derived from other data properties. They are ideal for cases where you need to perform some transformation or calculation on your data before displaying it.

Why Use Computed Properties?

  • Computed properties are cached.
  • They are only re-evaluated when one of their dependency’s changes.
  • This caching mechanism makes computed properties efficient for derived data, as Vue doesn’t need to recompute them on every render.
  • On the other hand, methods will be executed every time they are invoked, even if the underlying data has not changed, making them less efficient for tasks that don’t require frequent recalculations.

Syntax:

<script>
export default {
computed: {
computedProperty() {
// Computed logic here
}
}
};
</script>

Example:

<template>
  <div>
    <p>{{ countMessage }}</p>
    <button @click="increment">Click Me</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    };
  },
  computed: {
    countMessage() {
      return this.count > 5
        ? "You've clicked the button more than five times!"
        : "Keep clicking the button!";
    }
  },
  methods: {
    increment() {
      this.count++;
    }
  }
};
</script>

<style scoped>
button {
  padding: 10px 20px;
  font-size: 16px;
  background-color: #4CAF50;
  color: white;
  border: none;
  cursor: pointer;
}

button:hover {
  background-color: #45a049;
}
</style>

Output:

Img 1

After clicking the button more than five times

Img 2

countMessage is a computed property that changes depending on the value of count.
When count is greater than 5, countMessage will display “You’ve clicked the button more than five times!”.

Why Use Computed Properties Instead of Methods?

  •  Efficiency: Computed properties are cached and only re-evaluate when their dependencies change. This makes them more efficient, particularly in templates where they are accessed repeatedly.
  • Avoiding Unnecessary Recalculations: Methods are called every time the component re-renders, which can lead to unnecessary recalculations and potential performance issues. In contrast, computed properties only re-run when the data they depend on changes, making them more efficient for performance-sensitive operations.

Example of Methods for Comparison:

<template>
  <div>
    <p>{{ countMessage() }}</p>
    <button @click="increment">Click Me</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    };
  },
  methods: {
    increment() {
      this.count++;
    },
    countMessage() {
      // Method returns a message based on the count
      return this.count > 5
        ? "You've clicked the button more than five times!"
        : "Keep clicking the button!";
    }
  }
};
</script>

<style scoped>
button {
  padding: 10px 20px;
  font-size: 16px;
  background-color: #4CAF50;
  color: white;
  border: none;
  cursor: pointer;
}

button:hover {
  background-color: #45a049;
}
</style>

In this case, countMessage() will be re-executed every time the component re-renders, even if count hasn’t changed, which is less efficient than using a computed property.

Output:

Img 1

After clicking the button more than five times

Img 2

When to Use data() vs. Computed Properties

  1. Use data() to define the core state of your component (e.g., title, message, count, or userInfo). These are properties that you will directly manipulate and update.
  2. Use computed properties for derived values that depend on other state variables. For example, combining firstName and lastName into a fullName, or showing a conditional message based on count.

Conclusion

In Vue.js, the data() function is used to define a component’s reactive state, while interpolation allows dynamic data to be displayed in your templates. Computed properties provide an efficient way to derive values based on that state, optimizing performance by caching results. Together, these features make it easier to build dynamic, responsive applications that automatically update the UI without manual DOM manipulation.

]]>
https://blogs.perficient.com/2024/12/03/vuejs-data-interpolation-method-computed-properties/feed/ 0 372037
Understanding Vue.js Form Input Bindings: A Comprehensive Guide https://blogs.perficient.com/2024/11/28/vue-js-form-guide/ https://blogs.perficient.com/2024/11/28/vue-js-form-guide/#respond Thu, 28 Nov 2024 07:29:42 +0000 https://blogs.perficient.com/?p=371289

This blog explores how to work with various form inputs in Vue.js, such as text fields, checkboxes, radio buttons, select boxes, and more. Aimed at beginners, it focuses on Vue’s powerful data binding features for creating interactive forms in dynamic web applications.

Text Input Bindings

Text inputs are the most basic form elements, allowing users to enter single-line text. In Vue.js, you can use the ‘v-model’ directive to create a two-way data binding between the input element and the data property in your Vue instance.

Multiline Text Input

For multiline text input, you can use the <textarea> element, which also supports ‘v-model’ for two-way binding.

Checkbox Input

Checkboxes are great for boolean options. You can use ‘v-model’ to bind the checkbox’s checked state to a data property.

Radio Buttons

Radio buttons allow users to select one option from a group. Again, you can use ‘v-model’ to bind the selected value.

Select Dropdown

Select dropdowns let users choose one option from a list. Use ‘v-model’ to bind the selected value to a data property.

Multiselect Dropdown

For selecting multiple options, use the ‘<select>’ element with the ‘multiple’ attribute. ‘v-model’ can bind an array of selected values.

Value Bindings

Vue’s reactivity system makes it easy to manage and manipulate input values. You can also create computed properties or methods to handle complex scenarios, such as validating inputs or transforming data.

Example

Here’s a practical example that demonstrates how to implement these form input bindings in Vue.js:

<template>
  <div class="form-container">
    <h3>Vue.js Form Input Bindings</h3>

    <!-- Text Input with Validation -->
    <div class="text-input">
      <label for="username">Username:</label>
      <input id="username" v-model="username" placeholder="Enter your username" @blur="validateUsername" />
      <p v-if="usernameError" class="error">{{ usernameError }}</p>
      <p>Your username is: {{ username }}</p>
    </div>

    <!-- Multiline Text Input with Character Count -->
    <div class="multiline-input">
      <label for="description">Description:</label>
      <textarea id="description" v-model="description" placeholder="Enter a description" maxlength="200"></textarea>
      <p>Characters remaining: {{ 200 - description.length }}</p>
      <p>Your description is: {{ description }}</p>
    </div>

    <!-- Checkbox Input -->
    <div>
      <div class="checkbox-input">
        <input type="checkbox" id="agreement" v-model="isAgreed" />
        <label for="agreement">I agree to the terms</label>
      </div>
      <p>Agreement status: {{ isAgreed }}</p>
    </div>

    <!-- Radio Buttons -->
    <div class="radio-input">
      <label>Choose an option:</label>
      <label>
        <input type="radio" value="option1" v-model="selectedOption" />
        Option 1
      </label>
      <label>
        <input type="radio" value="option2" v-model="selectedOption" />
        Option 2
      </label>
      <p>Selected option: {{ selectedOption }}</p>
    </div>

    <!-- Select Dropdown with Dynamic Industries -->
    <div class="select-dropdown">
      <label for="industries">Select an industry:</label>
      <select id="industries" v-model="chosenIndustry">
        <option disabled value="">Select an industry</option>
        <option v-for="industry in industries" :key="industry">{{ industry }}</option>
      </select>
      <p>Selected industry: {{ chosenIndustry }}</p>
    </div>

    <!-- Multiselect Dropdown for Technologies -->
    <div class="multiselect-dropdown">
      <label for="multipleTechnologies">Select multiple technologies:</label>
      <select id="multipleTechnologies" v-model="selectedTechnologies" multiple>
        <option v-for="technology in technologies" :key="technology">{{ technology }}</option>
      </select>
      <p>Selected technologies: {{ selectedTechnologies.join(', ') }}</p>
    </div>

    <!-- Value Binding with Transformation -->
    <div class="value-binding">
      <label for="rawInput">Raw Input:</label>
      <input id="rawInput" v-model="rawInput" placeholder="Type something" />
      <p>Uppercase: {{ upperCasedInput }}</p>
      <p>Reversed: {{ reversedInput }}</p>
    </div>

    <!-- Submit Button -->
    <button @click="submitForm">Submit</button>
    <p v-if="submissionMessage">{{ submissionMessage }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      username: '',
      usernameError: '',
      description: '',
      isAgreed: false,
      selectedOption: '',
      chosenIndustry: '',
      selectedTechnologies: [],
      rawInput: '',
      industries: [],
      technologies: ['JavaScript', 'React.js', 'Next.js', 'Vue.js', 'SCSS'],
      submissionMessage: ''
    };
  },
  computed: {
    upperCasedInput() {
      return this.rawInput.toUpperCase();
    },
    reversedInput() {
      return this.rawInput.split('').reverse().join('');
    }
  },
  methods: {
    validateUsername() {
      this.usernameError = this.username.length < 3 ? 'Username must be at least 3 characters long.' : '';
    },
    async fetchIndustries() {
      // Simulating an asynchronous API call to fetch industries
      this.industries = await new Promise((resolve) => {
        setTimeout(() => {
          resolve(['Technology', 'Finance', 'Healthcare', 'Education', 'Retail']);
        }, 1000);
      });
    },
    submitForm() {
      if (this.usernameError || !this.isAgreed) {
        this.submissionMessage = 'Please fix the errors before submitting.';
        return;
      }
      this.submissionMessage = 'Form submitted successfully!';
      // Handle form submission logic here (e.g., API call)
    }
  },
  mounted() {
    this.fetchIndustries(); // Fetch industries on component mount
  }
};
</script>

<style scoped>
.form-container {
  max-width: 600px;
  margin: auto;
  padding: 20px;
  border: 1px solid #ccc;
  border-radius: 10px;
  background-color: #f9f9f9;
}

label {
  display: block;
  margin: 10px 0;
}
.checkbox-input {
 display: flex;
 align-items: center;
}
.checkbox-input label{
  margin: 0 0 0 10px;
}

.error {
  color: red;
}

.checkbox-input {
  display: flex;
  align-items: center;
}
</style>

Code Explanation

Template Section

  • Each form input is wrapped in a ‘div’, and we use ‘v-model’ to bind the input fields to corresponding data properties in the Vue instance.
  • For the text input and textarea, users can see their input reflected immediately in the paragraphs below.
  • The checkbox and radio buttons use ‘v-model’ to maintain their checked state and selected value.
  • The select and multiselect dropdowns allow users to choose from predefined options, with the selected values displayed dynamically.
  • The raw input field demonstrates how computed properties can transform input data (converting it to uppercase).

Script Section

  • The ‘data’ function returns an object containing the reactive properties used in the template.
  • The ‘computed’ property ‘upperCasedInput’ transforms the ‘rawInput’ to uppercase, showcasing Vue’s reactivity.

Style Section

  • Basic styling enhances the visual layout, ensuring that the form is easy to read and interact with.

Output:
Forminput

Real-World Applications

These input bindings can be applied in various real-world scenarios, such as:

  • User registration forms
  • Surveys and feedback forms
  • E-commerce checkout processes
  • Any application that requires user input

Conclusion

Vue.js provides a powerful and intuitive way to handle form inputs through its binding system. Whether you’re dealing with text inputs, checkboxes, or dropdowns, the ‘v-model’ directive simplifies managing state in your application. With these tools, you can create dynamic, responsive forms that enhance user experience.

Try implementing these Vue.js form bindings in your own projects, and feel free to share your experiences or questions in the comments below. Happy coding!

]]>
https://blogs.perficient.com/2024/11/28/vue-js-form-guide/feed/ 0 371289
Vue.js Components: A Guide to Building Scalable and Modular UIs https://blogs.perficient.com/2024/11/27/guide-to-vue-js-components/ https://blogs.perficient.com/2024/11/27/guide-to-vue-js-components/#comments Wed, 27 Nov 2024 08:39:46 +0000 https://blogs.perficient.com/?p=371829

In this blog, we’ll explore the importance of components, how to create them, and best practices for building modular, reusable UIs.

Why Vue Components Are Essential for Building Scalable UIs

Components are a core feature of Vue.js, known for its simplicity and flexibility. They serve as the building blocks of Vue applications, enabling developers to break down the user interface into smaller, self-contained units. This modular approach makes the code more organized, reusable, and straightforward.

  • Think of components as individual pieces of a puzzle.
  • Each one can be developed, tested, and maintained independently, and when combined, they create a fully functional application.
  • Whether it’s a button, a form, or a complex data table, components let you design modular UI elements that are easy to update.

What Are Vue Components?

In Vue, a component is a self-contained unit of functionality that includes a template, script, and optional styling. Components help modularize the UI, making it easier to reuse parts of the interface across different application parts.

Here’s an example of a Vue component for a simple button

//MyButton.vue
<template>
<button @click="handleClick">{{ label }}</button>
</template>

<script>
export default {
data() {
return {
label: 'Click Me'
};
},
methods: {
handleClick() {
alert('Button Clicked!');
}
}
};
</script>

<style scoped>
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
</style>

Breaking Down the Code

  1. Template: Defines the HTML structure of the component. In this case, it’s a simple button that displays the label.
  2. Script: Contains the logic, such as the data() function (for reactive properties) and the handleClick method (for the button’s behavior).
  3. Style: Scoped styling ensures the button’s styles are isolated to this component and won’t affect others in the app. This simple example demonstrates how components work as isolated units in Vue. However, as your app grows, organizing and managing components becomes crucial.

Why Use Components in Vue?

Vue components provide several advantages that contribute to building robust, maintainable, and scalable applications:

  • Reusability: Once defined, components can be used across multiple pages or sections of your app, reducing code duplication.
  • Modularity: Since components are isolated, you can change one without worrying about breaking other application parts.
  • Scalability: Start with small, focused components and quickly expand them into larger, more complex UIs as your application grows.

Advanced Component Features

Once you’re comfortable with basic components, Vue offers advanced features that make your components even more powerful:

Slots: The <slot></slot> tag in Vue lets you define placeholders within components that can accept dynamic content from parent components.

Example of a slot

<!-- Modal.vue -->
<template>
<div class="modal">
<div class="modal-content">
<slot></slot> <!-- Content inserted here will be rendered in the modal -->
</div>
</div>
</template>

Usage in a parent component

<Modal>
<h2>This is a Modal Title</h2>
<p>This content will go inside the modal.</p>
</Modal>

Dynamic Components: You can dynamically swap between different components using Vue’s component element and the: is an attribute is particularly useful for building tabbed interfaces or content that change based on user interaction.

Example of dynamically switching between components

Let’s walk through an example where we dynamically switch between different components using Vue’s component element and the :is attribute. In this example, we’ll create a button that lets you dynamically switch between different components.

Step-by-Step Example

Create components (e.g., ComponentA, ComponentB, ComponentC) to switch between. Next, build the MyButton component to manage dynamic component switching using the ‘:is’ attribute.

1. Create the Components (ComponentA, ComponentB, ComponentC)

Let’s define a few simple components to switch between.

<!-- ComponentA.vue -->
<template>
<div>
<h3>This is Component A</h3>
<p>Content for Component A.</p>
</div>
</template>

<script>
export default {
name: 'ComponentA',
};
</script>
<!-- ComponentB.vue -->
<template>
<div>
<h3>This is Component B</h3>
<p>Content for Component B.</p>
</div>
</template>

<script>
export default {
name: 'ComponentB',
};
</script>
<!-- ComponentC.vue -->
<template>
<div>
<h3>This is Component C</h3>
<p>Content for Component C.</p>
</div>
</template>

<script>
export default {
name: 'ComponentC',
};
</script>
2. Create the MyButton Component

Now, let’s create the MyButton component that will dynamically switch between ComponentA, ComponentB, and ComponentC using the: is attribute.

<!-- MyButton.vue -->
<template>
<div>
<!-- Button to change the current component -->
<button @click="changeComponent('ComponentA')">Show Component A</button>
<button @click="changeComponent('ComponentB')">Show Component B</button>
<button @click="changeComponent('ComponentC')">Show Component C</button>

<!-- Dynamic component rendering -->
<component :is="currentComponent"></component>
</div>
</template>

<script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';
import ComponentC from './ComponentC.vue';

export default {
name: 'MyButton',
components: {
ComponentA,
ComponentB,
ComponentC,
},
data() {
return {
currentComponent: 'ComponentA', // Default component to show
};
},
methods: {
changeComponent(componentName) {
this.currentComponent = componentName; // Update the current component based on button clicked
},
},
};
</script>

<style scoped>
button {
margin: 10px;
padding: 8px 12px;
background-color: #007bff;
color: white;
border: none;
cursor: pointer;
}

button:hover {
background-color: #0056b3;
}
</style>
3. Parent Component (App.vue)

Finally, let’s bring everything together in the App.vue file, where we will use MyButton to handle the dynamic component switching.

<!-- App.vue -->
<template>
<div id="app">
<h1>Dynamic Component Switcher</h1>
<MyButton />
</div>
</template>

<script>
import MyButton from './components/MyButton.vue';

export default {
name: 'App',
components: {
MyButton,
},
};
</script>

<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
text-align: center;
padding: 50px;
}

h1 {
font-size: 2em;
}
</style>
Output:

Img 1

After switching from ComponentA to ComponentB

Img 2

How It Works:
  1. Dynamic Component Rendering: In the MyButton.vue file, there’s a special line of code <component :is=”currentComponent”></component> that shows a different component based on the value of currentComponent. Initially, currentComponent is set to ‘ComponentA’, so ComponentA will be shown.
  2. Buttons: There are three buttons in the MyButton component. When you click one of them, it calls the changeComponent() method, which updates the currentComponent value to the name of the component you clicked (either ComponentA, ComponentB, or ComponentC). This change automatically updates the displayed component.So, the button clicks switch between different components on the screen.

Results

When you run the app
  • The initial view will show Component A.
  • Clicking on the buttons will dynamically switch to Component B or Component C based on the button clicked.

Summary: This setup uses Vue’s <component :is=”…”> element to dynamically swap between different components, which is particularly useful for building interactive interfaces like tabbed views or conditional content displays based on user actions.

Best Practices for Organizing Vue Components

As your Vue application grows, organizing your components efficiently is essential. Here are a few tips to help you keep everything neat and maintainable:

  • Atomic Design: Divide your UI into smaller, reusable components. Start with atomic components like buttons and inputs and then combine them into larger structures like forms and navigation bars.
  • Folder Structure: To keep your project organized, group components by functionality or UI sections. For example, you might have folders like /components/buttons, /components/forms, and /components/layouts.
  • Naming Conventions: Give components meaningful names that describe their purpose. This will help you (and your team) understand what each component does at a glance.

Optimizing Performance with Vue Components

Vue allows you to improve performance when working with components:

  1. Lazy Loading: You can use dynamic `import()` to load components only when needed, which helps reduce the initial bundle size and improves page load times.
  2. v-if vs. v-show: Use v-if for conditionally rendering components only when necessary. This prevents unnecessary rendering and can improve performance.

Conclusion

Vue.js components are powerful for building clean, maintainable, and scalable user interfaces. By breaking your app into smaller, reusable parts, you can improve both development efficiency and the long-term maintainability of your project. Whether working on simple UI elements or building complex applications, mastering Vue components will set you on the path to success.

Start creating your Vue.js components today, and watch your application grow modularly with each new feature!

]]>
https://blogs.perficient.com/2024/11/27/guide-to-vue-js-components/feed/ 1 371829
Custom Date Range Picker in Vue.js – Complete Guide https://blogs.perficient.com/2024/11/21/custom-date-range-picker-in-vue-js-complete-guide/ https://blogs.perficient.com/2024/11/21/custom-date-range-picker-in-vue-js-complete-guide/#respond Fri, 22 Nov 2024 04:26:57 +0000 https://blogs.perficient.com/?p=370041

In this blog, we will explore how to create a custom date range picker in Vue.js that is both functional and visually appealing. We’ll also explore advanced customizations such as custom date formatting, controlling calendar visibility, and managing custom CSS classes.

Benefits of Using a Custom Date Range Picker in Vue.js

Creating a custom date range picker in Vue.js not only enhances the user interface but also provides users with flexibility in selecting date ranges. By implementing this component, you can offer features like dynamic date selection and improved visual customization, making your application more user-friendly.

Step 1: Installing and Importing Dependencies for the Date Range Picker Component

We will start by installing the required package.

Installing And Importing Dependencies

 

In your component, import the vue2-daterange-picker

Import

Step 2: Template Setup for the Custom Date Range Picker

Next, we’ll add the DateRangePicker to the template. We’ll allow users to clear dates, show or hide calendar arrows, and manage other configurations dynamically:

Template

Step 3: Script Setup with Customizations for the Date Range Picker

In this step, we’ll define the logic of the Date Range Picker component and add various customizations. This involves setting up props, methods, and watchers.

1. Import Required Dependencies

We start by importing the necessary components and decorators:

Import Required Dependencies

2. Define the Component and Props

Set up the component using the @Component decorator and define the required props. These props offer flexibility for customizing features like date ranges, time pickers, calendar behavior, etc.

Define the Component and Props

Each prop defines a feature of the Date Range Picker, such as minDate and maxDate to control the date range, timePicker options for time selection, and opens to specify where the calendar appears.

3. Add Data Properties

Define internal data properties for the component, including isSelectedDatePicker and dateRange to track the current date selection:

Add Data Properties

4. Set Up the Mounted Hook

In the mounted lifecycle hook, we initialize the Date Range Picker by setting custom attributes on the DOM element, like disabling content editing and setting a placeholder:

Set Up the Mounted Hook

5. Create a Method to Clear Dates

Create a method to reset the picker and clear the chosen date range

Create a Method to Clear Dates

6. Handle Date Selection Changes

Create a method to handle when the user selects a date. This updates the date range and emits an event:

Handle Date Selection Changes

7. Add Watchers for Start and End Date Changes

Watch for changes in startDate and endDate and update the date range accordingly. This ensures that any external changes to these props will reflect in the Date Range Picker:

Add Watchers for Start and End Date Changes

Step 4: Add Advanced Features to the Custom Date Range Picker

Custom Time Pickers: If your users need to select specific times, you can add time picker functionality:

Custom Time Pickers

Appending the Calendar to the Body: For better control over positioning and styles, you can append the calendar to the body:

Appending the Calendar to the Body

Handling Calendar Positioning: You can control whether the calendar opens to the left, right, or center:

Handling Calendar Positioning 

Close on Escape: Allow the picker to close when the escape key is pressed:

Close on Escape

Step 5: Handling Event Emissions from the Date Range Picker

We can emit custom events when the date changes, allowing the parent component to react to changes:

Handling Event Emissions

This event can be handled in the parent component to update other parts of the app based on the selected date range.

Conclusion

By using vue2-daterange-picker, you can easily create a customizable Date Range Picker component that fits your project’s needs. You can extend its functionality with advanced customizations like time pickers, calendar positioning, appending to the body, and more. With the right styling and event handling, you can make your Date Range Picker fit perfectly into your application.

If you’re looking for more detailed documentation, you can check out the official vue2-daterange-picker documentation.

]]>
https://blogs.perficient.com/2024/11/21/custom-date-range-picker-in-vue-js-complete-guide/feed/ 0 370041
Creating a Dual List Box Component in Vue.js https://blogs.perficient.com/2024/11/21/creating-a-dual-list-box-component-in-vue-js/ https://blogs.perficient.com/2024/11/21/creating-a-dual-list-box-component-in-vue-js/#respond Thu, 21 Nov 2024 13:41:32 +0000 https://blogs.perficient.com/?p=369896

A dual list box is a commonly used UI component in Vue.js that allows users to select items from one list (the source) and move them to another (the destination). This component is ideal for scenarios where users need to select multiple items from a large list, offering functionality to filter, search, and select items easily.

In this blog, we’ll learn how to build a dual list box component in Vue.js using TypeScript, highlighting features such as searching, filtering, and moving items between the lists.

Features of the Dual List Box

  • Search functionality for refining list items.
  • Move single or multiple items between lists.
  • Filter items based on their status (e.g., active or inactive).
  • Support for keyboard interactions like Ctrl + Click to select multiple items.

Step 1: Setting Up the Project

Before diving into building the component, let’s first set up the project. We’ll begin by installing the necessary dependencies to get started.

Step 1.1: Install Vue and Vue-Property-Decorator

To start, open your terminal and run the following command to install Vue and the vue-property-decorator package, which we’ll use to leverage TypeScript decorators:

Install Basic Components

Step 1.2: Create the DualListBox.vue File

Next, navigate to the components directory of your Vue project and create a new file called DualListBox.vue. This file will serve as the foundation for our component. We’ll define the structure for two key sections: one for available items and one for selected items, with buttons in between to move items back and forth.

Explore more on setting up Vue projects in this detailed guide from Vue Mastery

Step 2: Create the Layout for Available Items

With the project setup complete, let’s move on to creating the layout for the available items section. This part will include the search functionality, item counts, and filtering options.

Step 2.1: Search Box for Available Items

To help users refine the available items, add a search input field. This input will be bound to the searchSource data property, allowing users to filter items dynamically.

Search Box For Available Items

Step 2.2: Display Available Items Count

After adding the search input, it’s useful to show users the number of items matching the search criteria. We can display the count of filtered items alongside the total number of available items.

Display Available Items Count

Step 2.3: Add Checkbox for Active Items

In some cases, users may want to filter items based on their status (e.g., active or inactive). To provide this option, include a checkbox that filters active items, controlled by the activeItems property.

Add Checkbox For Active Items

Step 2.4: List of Available Items

Now, we’ll display the available items in a list. Each item will be clickable, allowing users to select it and move it to the selected items list.

List Of Available Items

Step 3: Add Buttons to Move Items

Between the available and selected items lists, we need buttons to facilitate the movement of items. These buttons allow users to move items between the two lists, either one at a time or all at once.

Add Buttons To Move Items

Step 4: Create the Layout for Selected Items

Next, we’ll create the layout for the selected items section. This part mirrors the available items section, with search, filtering, and item display functionalities.

Step 4.1: Search Box for Selected Items

To allow users to search through the selected items, add a search input bound to searchDestination.

Search Box For Selected Items

Step 4.2: Display Selected Items Count

Just like the available items section, show the count of filtered and total items in the selected list.

Display Selected Items Count

Step 4.3: List of Selected Items

Finally, we’ll display the selected items, allowing users to click on them to remove them from the list.

List Of Selected Items

Step 5: Defining Properties and Data

Now that the template is in place, let’s move to the script section. We’ll define the properties and data needed to manage the lists and interactions. Use @Prop to accept availableItems and selectedItems from the parent component.

Define Properties And Data

Step 6: Implementing Filtered Lists

To ensure the search and filter functionalities work as intended, create computed properties that return the filtered lists based on search terms and item status.

Get Filtered Lists

Step 7: Implementing the Move Logic

Next, implement the methods that handle moving items between the available and selected lists. These include:

  • moveToDestination for moving selected items from available to selected.
  • moveToSource for moving items back to available.
  • moveAllToDestination to move all available items.
  • moveAllToSource to move all selected items back.

Implementing Move Logic

Step 8: Emitting Events to the Parent Component

When items are moved between lists, we’ll emit an event to notify the parent component to update its state. Here’s an example of emitting the onChangeList event:

Emitting Events To Parent Component

In the parent component, listen for this event to update the selected and available items accordingly.

Listen For Event In Parent

For further reading on event handling in Vue.js, check out the official Vue documentation on event handling.

Step 9: Styling the Component

Finally, add CSS styles to make the dual list box visually appealing. You can customize the list boxes, buttons, and search inputs to match your design requirements.

Styling The Component

Conclusion

In this tutorial, you’ve built a dual list box component using Vue.js with TypeScript. This component allows users to move items between two lists, search within the lists, and filter items by status. You can extend this component further by adding features like drag-and-drop or keyboard navigation.

]]>
https://blogs.perficient.com/2024/11/21/creating-a-dual-list-box-component-in-vue-js/feed/ 0 369896