[Vuejs]-Vue 2 Infinite Loop Across Parent and Child Component Using Slots

0👍

The following bindings to the toggle function do not make any sense to me:

:toggleLeft="toggle('left')"
:toggleRight="toggle('right')

Since the function does not return any value, it’s simply wrong.

The both bindings cause the function to be called endlessly with toggle('left') and toggle('right')

Just add console.log(direction) to the toggle function to see what’s going on.

JS Console output

If you want to get an advice about the right solution, then please describe what you are trying to achieve.

Vue.component('toggle-buttons',{
  props: {
    leftSelectedInitially: {
        type: Boolean,
        default: true,
    }
  },
  data() {
      return {
          leftSelected: true,
          rightSelected: false,
      }
  },
  beforeMount() {
      //this.leftSelected = this.leftSelectedInitially;
      //this.rightSelected = !this.leftSelectedInitially;
  },
  methods: {
      toggle(override) {
          console.log(`override: ${override}`)
          this.leftSelected = override == 'left';
          this.rightSelected = override == 'right';
      }
  },
  template: `
<div role="list">
  <div role="listitem">
      <slot name="left" :is-selected="leftSelected" :toggleLeft="toggle('left')" />
  </div>
  <div role="listitem">
      <slot name="right" :is-selected="rightSelected" :toggleRight="toggle('right')" />
  </div>
</div>
`
});

new Vue({
  el:'#app',
  methods: {
  toggle(direction) {
    console.log(`direction: ${direction}`)
    this.$refs.tb.toggle(direction);
    }
  }
})
#app { line-height: 2; }
[v-cloak] { display: none; }
<div id="app">
<toggle-buttons ref="tb">
    <template v-slot:left="{ isSelected }">
        <button
            class="button"
            :class="{ secondary: !isSelected }"
            :aria-pressed="isSelected"
            :togglable="true"
            v-text="'left'"
            @click="toggle('left')"
        />
    </template>
    <template v-slot:right="{ isSelected }">
        <button
            class="button"
            :class="{ secondary: !isSelected }"
            :aria-pressed="isSelected"
            :togglable="true"
            v-text="'right'"
            @click="toggle('right')"
        />
    </template>
</toggle-buttons>
</div>
<script src="https://unpkg.com/vue@2/dist/vue.min.js"></script>

Leave a comment