user6189981
user6189981

Reputation:

VueJS Custom dropdown buttons not working independently of each other

So I have a button dropdown which is working as expected but I have a bug where I can't reuse the same component as they both dont work independently of each other but instead when one is clicked the other changes too.

Please find a JSFiddle below and my code.

Thanks

<div id="app">
                <div v-on:click="menuVisible = !menuVisible" class="dropdownBtn">
                    <div v-bind:class="{ active : menuVisible }"class="dropdownBtn__title">
                        <span v-if="!btnTitle">exploring</span>
                        <span v-else>{{ btnTitle }}</span>
                    </div>
                    <div v-show="menuVisible" class="dropdownBtn__content">
                        <ul v-for="reason in reasons">
                            <li v-on:click="updateTitle(reason)">{{ reason.title }}</li>
                        </ul>
                    </div>
                </div>
  <div v-on:click="menuVisible = !menuVisible" class="dropdownBtn">
                    <div v-bind:class="{ active : menuVisible }"class="dropdownBtn__title">
                        <span v-if="!btnTitle">exploring</span>
                        <span v-else>{{ btnTitle }}</span>
                    </div>
                    <div v-show="menuVisible" class="dropdownBtn__content">
                        <ul v-for="reason in reasons">
                            <li v-on:click="updateTitle(reason)">{{ reason.title }}</li>
                        </ul>
                    </div>
                </div>
</div>


new Vue({
  el: '#app',
  data() {
        return {
            menuVisible: false,
            btnTitle: false,
            reasons: [{
                title: 'family fun',
                value: 1
            },
            {
                title: 'relaxing',
                value: 2
            },
            {
                title: 'dining',
                value: 3
            },
            {
                title: 'meetings & events',
                value: 4
            },
            {
                title: 'what\'s on',
                value: 5
            },
            {
                title: 'gold',
                value: 6
            }]
        }
    },
    methods: {
        updateTitle($event) {
            this.btnTitle = $event.title
        }
    }
})

Upvotes: 0

Views: 657

Answers (1)

thanksd
thanksd

Reputation: 55644

So, for one, you haven't actually made a reusable component for the dropdown. You need to define that using Vue.component. Then you can use the tag for the custom component in the root template.

Secondly, if you are binding to the same data, then that is what will be reflected in both templates. You'll still need to pass separate data to the two separate dropdown components.

Vue.component('dropdown', {
  template: `
    <div v-on:click="menuVisible = !menuVisible" class="dropdownBtn">
      <div v-bind:class="{ active : menuVisible }"class="dropdownBtn__title">
        <span v-if="!btnTitle">exploring</span>
        <span v-else>{{ btnTitle }}</span>
      </div>
      <div v-show="menuVisible" class="dropdownBtn__content">
        <ul v-for="reason in reasons">
          <li v-on:click="updateTitle(reason)">{{ reason.title }}</li>
        </ul>
      </div>
    </div>
  `,
  props: ['menuVisible', 'btnTitle', 'reasons'],
  methods: {
    updateTitle($event) {
      this.btnTitle = $event.title
    }
  }
})

new Vue({
  el: '#app',
  data() {
    return {
      fooReasons: [
        { title: 'family fun', value: 1 },
        { title: 'relaxing', value: 2 },
        { title: 'dining', value: 3 },
        { title: 'meetings & events', value: 4 },
        { title: 'what\'s on', value: 5 },
        { title: 'gold', value: 6 }
      ],
      barReasons: [
        { title: 'family bar', value: 1 },
        { title: 'bar relaxing', value: 2 },
        { title: 'bar dining', value: 3 },
        { title: 'meetings & bars', value: 4 },
        { title: 'bar\'s on', value: 5 },
        { title: 'gold bar', value: 6 }
      ]
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="app">
  <dropdown :menu-visible="false" :btn-title="false" :reasons="fooReasons"></dropdown>
  <dropdown :menu-visible="false" :btn-title="false" :reasons="barReasons"></dropdown>
</div>

Upvotes: 1

Related Questions