[Vuejs]-Toggling classes with Vue Js, grabbing all props from the component

3👍

You’re kind of HTML-oriented in your approach, here, and the Vue approach is to be model-oriented. So instead of laying out your model structure in the HTML, you should make a data model with the hierarchy you want, and have your components render it.

I made my app the section level, since you’re concerned with what happens below that level. I created a data model like the first section of your example.

The trick to select-only-one behavior is that there should be one variable to hold the currently selected value. That value is owned by the parent. Each child gets a prop telling it whether it is the selected value.

When a child becomes selected, it emits an event, which the parent processes (this is the Vue way of child-to-parent communication).

Vue.component('nav-child', {
  template: '#nav-child-template',
  props: ['name', 'url']
});

Vue.component('nav-item', {
  template: '#nav-item-template',
  props: ['name', 'children', 'isActive'],
  methods: {
    toggleClass() {
      this.$emit('activate', this.isActive ? null : this.name);
    }
  }
});

new Vue({
  el: '#nav-section',
  data: {
    activeItem: null,
    items: [{
        name: 'Home',
        children: [{
            name: 'Dashboard 1',
            url: '#'
          },
          {
            name: 'Dashboard 2',
            url: '#'
          }
        ]
      },
      {
        name: 'Settings',
        children: [{
            name: 'Setting 1',
            url: '#'
          },
          {
            name: 'Setting 2',
            url: '#'
          }
        ]
      }
    ]
  },
  methods: {
    activate(name) {
      this.activeItem = name;
    }
  }
});
.active {
  border: thin solid red;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<template id="nav-child-template">
    <li>
        <a :href="url">{{ name }}</a>
    </li>
</template>

<template id="nav-item-template">
    <li>
        <a @click="toggleClass">{{ name }}</a>

        <ul :class="{ 'active': isActive}">
            <li is="nav-child" v-for="child in children" :name="child.name" :url="child.url"></li>
        </ul>
    </li>
</template>

<ul id="nav-section">
  <li is="nav-item" v-for="item in items" :name="item.name" :is-active="activeItem === item.name" :children="item.children" @activate="activate"></li>
</ul>
👤Roy J

Leave a comment