Meaning of v-slot:activator="{ on }" Meaning of v-slot:activator="{ on }" vue.js vue.js

Meaning of v-slot:activator="{ on }"


You're likely referring to this example:

<v-toolbar color="grey darken-1" dark>  <v-menu :nudge-width="100">    <template v-slot:activator="{ on }">      <v-toolbar-title v-on="on">        <span>All</span>        <v-icon dark>arrow_drop_down</v-icon>      </v-toolbar-title>    </template>    ...  </v-menu></v-toolbar>

The following line declares a scoped slot named activator, and it is provided a scope object (from VMenu), which contains a property named on:

<template v-slot:activator="{ on }">

This uses destructuring syntax on the scope object, which IE does not support.

For IE, you'd have to dereference on from the scope object itself:

<template v-slot:activator="scope">  <v-toolbar-title v-on="scope.on">

But the ideal solution IMO is to use a Vue CLI generated project, which includes a Babel preset (@vue/babel-preset-app) to automatically include the transforms/polyfills needed for the target browsers. In this case, babel-plugin-transform-es2015-destructuring would be automatically applied during the build.

Details on the activator slot

VMenu allows users to specify a slotted template named activator, containing component(s) that activate/open the menu upon certain events (e.g., click). VMenu provides listeners for those events via an object, passed to the activator slot:

<v-menu>  <template v-slot:activator="scopeDataFromVMenu">    <!-- slot content goes here -->  </template></v-menu>

The slot content can access VMenu's event listeners like this:

<v-menu>  <template v-slot:activator="scopeDataFromVMenu">    <button v-on="scopeDataFromVMenu.on">Click</button>  </template></v-menu>

For improved readability, the scoped data can also be destructured in the template:

<!-- equivalent to above --><v-menu>  <template v-slot:activator="{ on }">    <button v-on="on">Click</button>  </template></v-menu>

The listeners from the scope object are passed to the <button> with v-on's object syntax, which binds one or more event/listener pairs to the element. For this value of on:

{  click: activatorClickHandler // activatorClickHandler is an internal VMenu mixin}

...the button's click handler is bound to a VMenu method.


I think the original question is about understanding the "on" object. It is best explained here:

https://github.com/vuetifyjs/vuetify/issues/6866

Essentially "on" is a prop passed in from the activator. What v-on="on" does is bind that on prop to the component. "on" itself is all of the event listeners passed from the activator.


To call out a readability tip, it's possible to use this syntax:

<v-menu>    <template v-slot:activator="{ on: activationEvents }">        <v-btn v-on="activationEvents">            I like turtles 🐢        </v-btn>    </template></v-menu>

In my brain this has a more fluent readability than v-on="on", which to me is like observing a conversation consisting solely of:

  • Person 1: "Hey"
  • Person 2: "Yep"

Understand? ;)

By the way, activationEvents could be any alias, like "slotEvents", "listeners", "anyOldEvent", or whatever makes more sense to the reader as a renaming of the mysterious on.