13
votes

How to use v-tooltip inside v-menu activator with vuetify 2.0? Previously it was working using slot="activator".

That's what I'm trying to combine:

<v-menu>
  <template v-slot:activator="{on}">
    <v-btn v-on="on">Menu Trigger</v-btn>
  </template>
  ...list with menu options...
</v-menu>

and

<v-tooltip v-slot:activator="{on}">
  <v-btn v-on="on">Menu Trigger with Tooltip</v-btn>
  <span>Tooltip Content</span>
</v-tooltip>

Now I try to paste v-tooltip inside v-menu, what should happen with {on} here?

1

1 Answers

35
votes

I think you're most likely unsure about the "conflicted" on objects passed to the template by multiple activator slots and how to apply all of the event handlers on the target element(s).

If that's the case, you can workaround this by assigning either one (or both) of them to a variable with a different name (see: assigning to new variable names), and then destructure and "restructure", which basically glues them back together (or merge them, technically speaking).

<v-menu>
  <template #activator="{ on: onMenu }">
    <v-btn v-on="onMenu">Menu Trigger</v-btn>

    <v-tooltip bottom>
      <template #activator="{ on: onTooltip }">
        <v-btn v-on="{ ...onMenu, ...onTooltip }">Menu Trigger with Tooltip</v-btn>
      </template>

      <span>Tooltip Content</span>
    </v-tooltip>
  </template>

  <!-- ...list with menu options... -->
</v-menu>

Or, use the slot props directly. Just make sure to name them properly so they won't introduce another naming conflict with the component's data and/or props.

<v-menu>
  <template #activator="menu">
    <v-btn v-on="menu.on">Menu Trigger</v-btn>

    <v-tooltip bottom>
      <template #activator="tooltip">
        <v-btn v-on="{ ...menu.on, ...tooltip.on }">Menu Trigger with Tooltip</v-btn>
      </template>

      <span>Tooltip Content</span>
    </v-tooltip>
  </template>

  <!-- ...list with menu options... -->
</v-menu>

Complete Demo:

new Vue({
  el: '#app',

  data: () => ({
    items: [
      { title: 'Item #1' },
      { title: 'Item #2' },
      { title: 'Item #3' }
    ]
  })
})
<link href="https://fonts.googleapis.com/css?family=Roboto:400|Material+Icons" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>

<div id="app">
  <v-menu>
    <template #activator="{ on: onMenu }">
      <v-btn v-on="onMenu">Menu Trigger</v-btn>

      <v-tooltip bottom>
        <template #activator="{ on: onTooltip }">
          <v-btn v-on="{ ...onMenu, ...onTooltip }">Menu Trigger with Tooltip</v-btn>
        </template>

        <span>Tooltip Content</span>
      </v-tooltip>
    </template>

    <v-list>
      <v-list-tile 
        v-for="(item, index) in items" :key="index"
        @click.prevent>
        <v-list-tile-title>{{ item.title }}</v-list-tile-title>
      </v-list-tile>
    </v-list>
  </v-menu>
</div>