vuetify: [Bug Report] v-menu: item in activator slot disappears when pushing route

EDIT: repro https://github.com/vuetifyjs/vuetify/issues/10578#issuecomment-612163991

Environment

Vuetify Version: 2.2.12 Vue Version: 2.6.11 Browsers: Chrome 80.0.3987.100 OS: Linux x86_64

Steps to reproduce

  1. Add a v-menu like the following:
    <v-menu
      ref="date-picker"
      v-model="showingPicker"
      :close-on-content-click="false"
      offset-y
      max-width="290px"
      min-width="290px"
    >
      <template v-slot:activator="{ on }">
        <v-text-field
          v-model="dateFormatted"
          hint="MM/DD/YYYY format"
          persistent-hint
          :outlined="true"
          append-icon="mdi-calendar"
          @blur="updatedInputDate()"
          v-on="on"
        ></v-text-field>
      </template>
      <v-date-picker v-model="date" no-title @input="selectedCalendarDate()"></v-date-picker>
    </v-menu>
  1. Navigate to another view via: this.$router.push('/somewhere').
  2. The v-text-field element will disappear

Expected Behavior

The v-text-field element should not disappear

Actual Behavior

The v-text-field element will disappear

Other comments

Also, is it possible attach v-on to the @click:append-icon event?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 11
  • Comments: 41 (2 by maintainers)

Commits related to this issue

Most upvoted comments

This problem is related to transitions aplied to routes and the use of v-slot:activador. In my projects I use a app-bar with some buttons with tooltips. Instead of using v-slot:activator, I have used the props activator in tooltips. Example: v-slot:activator

<v-tooltip bottom>   
  <template v-slot:activator="{ on, attrs }">  
    <v-btn color="primary" dark v-bind="attrs" v-on="on">
      Button
    </v-btn>
  </template>
  <span>Tooltip</span>
</v-tooltip>

Props activator

<v-btn id="bt_button" color="primary" dark>
  Button
  <v-tooltip bottom activator="#bt_button">
    <span>Tooltip</span>
  </v-tooltip>
</v-btn>

This problem can be seen in many others v-slot:activator, including v-menu.

I am having this issue. Whenever route changed, the element in <template v-slot:activator="{ on }">...</> disappears…

The problem is related to the transitions feature on the router in nuxt.

By disabling the transitions feature in nuxt.config, the problem disappear. So hope this clue will help you find a solution to be able to enable transition on router and fix the problem in vuetify.

...
  features: {
    transitions: false
  },
...

I had pretty much the same issue, I solved it by adding the attach prop on my v-menu.

<v-menu
  bottom
  left
  origin="top right"
  attach="">

Maybe it can also help here 😃

looking for a fix as well without nuxt

I think I found out a situation where it is happening, and how to solve it. At least in my case.

When the structure inside the <template v-slot:activator="{ on }"> ... </template> changes. The rendering breaks. So if you have a v-if inside that template that switches between different elements, it breaks.

Can somebody confirm this?

We actually ended up swapping this component out but I will try to create a vanilla reproduction case this week. That said, I can tell you it is still happening in our code if I add the control back.

I was having similar issues and I decided to actually debug through Vue rendering code to understand what’s going on. It seems like for some reason the activator slot of v-list-group is treated as a scoped slot and when normalizeScopedSlots() is invoked, it’s correctly attached to the main $slots property making it available through $slots.activator.

But then on subsequent re-renders it skips the normalizeScopedSlots() algorithm (because slots._normalized is set) and when that happens it no longer attaches the $scopedSlots.activator function to $slots. And then this.$slots.activator becomes undefined in the v-list-group render function.

On top of this: I checked Vue docs and Vue suggests always using this.$scopedSlots in render functions, even when dealing with the basic kind of slots (source):

If you work with render functions, it is now recommended to always access slots via $scopedSlots, whether they currently use a scope or not. This will not only make future refactors to add a scope simpler, but also ease your eventual migration to Vue 3, where all slots will be functions.

And if you check the source code of v-list-group in this repo, the render function only uses this.$slots.

So what is the solution?

To define the activator slot using the old syntax that attaches it to $slots not $scopedSlots.

So do it like this:

          <template slot="activator">
               ...
          </template>

Not like this:

          <template #activator>
               ...
          </template>

As @eikooc commented I had this issue because the only child of <template v-slot:activator="{ on }"></template> had a v-if that was toggling it’s visibility.

I solved it by wrapping the “activator button” (<my-button> in this example) in a div that is not bound to the v-if:

<v-menu
  v-model="isMenuOpen"
  v-bind="{...otherAttrs}"
>
  <template v-slot:activator="{ on }">
    <div>
      <my-button
        v-if="condition"
        @click="isMenuOpen = !isMenuOpen"
        v-on="on"
      >
        Some text
      </my-button>
    </div>
  </template>

  <v-card>Menu content...</v-card>
</v-menu>

Good for ya. 😃 What about in a Vue stack that doesn’t have Nuxt… like in my examples?

I tried to reproduce it and I found that I am not able to reproduce it only with Vuetify and vue-router. But I was able to reproduce it with nuxt. I dont know why within nuxt the problem is present.

I prepared a simple codesandbox to show this.

https://w63ms.sse.codesandbox.io/

Scenario: By navigation from /about to home page, The dropdown button dissapear until the Home page is rendered completely.

@eikooc this is not look like to be related to structure inside template v-slot

@jacekkarczmarczyk Is it possible to investigate and maybe reopen the issue?