Implementing a Tab Switcher in Vue 2 Using Dynamic Components and v-for

<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Tab Switcher Example</title>
  <script src="vue.js"></script>
  <style>
    .tab-label {
      background: #ccc;
      padding: 2px 5px;
      line-height: 30px;
      text-align: center;
      cursor: pointer;
      margin-right: 4px;
    }
    .tab-label.active {
      color: #fff;
      background: green;
    }
  </style>
</head>
<body>
  <div id="app">
    <component :is="currentView"></component>
    <span
      v-for="(tab, index) in tabs"
      :key="index"
      :class="{ active: selectedIndex === index }"
      class="tab-label"
      @click="switchTab(index)"
    >
      {{ tab.label }}
    </span>
  </div>

  <script>
    const PanelA = { template: '<div>Content of Tab A</div>' };
    const PanelB = { template: '<div>Content of Tab B</div>' };
    const PanelC = { template: '<div>Content of Tab C</div>' };

    new Vue({
      el: '#app',
      data() {
        return {
          currentView: 'PanelA',
          selectedIndex: 0,
          tabs: [
            { label: 'Tab 1', component: 'PanelA' },
            { label: 'Tab 2', component: 'PanelB' },
            { label: 'Tab 3', component: 'PanelC' }
          ]
        };
      },
      methods: {
        switchTab(index) {
          this.selectedIndex = index;
          this.currentView = this.tabs[index].component;
        }
      },
      components: {
        PanelA,
        PanelB,
        PanelC
      }
    });
  </script>
</body>
</html>

This implementation uses Vue 2’s dynamic component feature with :is to render the active tab content. The tab labels are generated via v-for, binding click events to update both the selected index and the current component.

Key points:

  • The :class directive toggles the active class based on selectedIndex, avoiding manual array mutation.
  • Direct assignment too selectedIndex and currentView ensures reactivity without needing Vue.set or $set, since these properties are declared in the initial data() object.
  • Each tab entry stores its associated component name, enabling clean mapping between UI and dynamic content.

This approach simplifies state management and avoids unnecessary complexity while maintaining full reactivity.

Tags: vue2 dynamic-components Tabs UI frontend

Posted on Sun, 11 Oct 2026 16:03:32 +0000 by deadlyp99