0

I have the following code which uses this VueTailwind package:

<t-dropdown>
<div
    slot="trigger"
    slot-scope="{mousedownHandler, focusHandler, blurHandler, keydownHandler}"
>
    <button
        id="reseller-menu"
        aria-label="User menu"
        aria-haspopup="true"
        @mousedown="mousedownHandler"
        @focus="focusHandler"
        @blur="blurHandler"
        @keydown="keydownHandler"
    >
        {{ $page.props.auth.user.reseller.name }}
        <icon icon="chevron-down" class-name="ml-2" />
    </button>
</div>

<div slot-scope="{ blurHandler }">
    <span v-for="user in users" :key="reseller.id" role="menuitem" class="block px-6 cursor-pointer py-2 hover:bg-indigo-500 hover:text-white"
         @click="changeUser(user.id); blurHandler">{{ user.name }}</span>
</div>
</t-dropdown>

However, the blurHandler is not executed whenever the changeUser(user.id) method (a method in the parent component which seems to execute fine) is added to the @click event. The only way I was able to solve this issue was to use two different events such as the following:

<span v-for="user in users" :key="reseller.id" role="menuitem" class="block px-6 cursor-pointer py-2 hover:bg-indigo-500 hover:text-white"
         @click="changeUser(user.id)" @mouseup="blurHandler">{{ user.name }}</span>

How can I use both in the same event since this doesn't seem to work in this case?

tony19
  • 125,647
  • 18
  • 229
  • 307
Matthew Knill
  • 252
  • 2
  • 7

1 Answers1

2

When the v-on value is a function reference, the template compiler transforms it into a function call, passing the event argument:

<button @click="functionRef">

<!-- ...is transformed into: -->

<button @click="functionRef($event)">

But when the v-on value is an expression, the template compiler wraps it in a function:

<button @click="onClick(); functionRef">

<!-- ...is transformed into: -->

<button @click="() => { onClick(); functionRef; }">

Notice functionRef; is not a function call, and effectively does nothing. To actually invoke the function in that expression, add the parentheses to make it a call:

<button @click="onClick(); functionRef()">

So your markup should be:

<div slot-scope="{ blurHandler }">
    <span v-for="user in users" ⋯                 
          @click="changeUser(user.id); blurHandler()">
        {{ user.name }}
    </span>
</div>

Also note slot-scope has been deprecated for v-slot, as of 2.6.0.

tony19
  • 125,647
  • 18
  • 229
  • 307
  • Indeed, if `blurHandler` needs to access the event arg (e.g., to get the event source), the `$event` would have to be passed on as well. – tony19 Jan 29 '22 at 05:12