Search code examples
vuejs3vuetify.js

Access $vuetify in vue3 plugin


I'm trying to make a vue3 plugin that needs access to $vuetify for some theme related work. I tried several things but can't make it work.

My plugin looks like this

export const ColorPlugin: Plugin = {
    install: (app) => {
        app.config.globalProperties.$color = function(this: InstanceType<DefineComponent>, key: string): string {
            let color = (this.$vuetify as any).theme.current.colors[key];

            // Do some work on the color

            return color;
        }
    }
}

I import the plugin like this

export function registerPlugins (app: App) {
  loadFonts();
  app.use(vuetify).use(ColorPlugin);
}

...

const app = createApp(App);
registerPlugins(app);
app.mount('#app');

And I've got some components defined as

<template>
  <div :style="wrapperStyle">
    <v-icon v-if="icon" :color="$color(color)">
      {{ icon }}
    </v-icon>
    <span v-if="label">
      {{ label }}
    </span>
  </div>
</template>

<script lang="ts">
import { defineComponent, getCurrentInstance, PropType } from "vue";

export default defineComponent({
  name: "FSLabelWithIcon",
  props: {
    icon: {
      type: String,
      required: false,
      default: null
    },
    label: {
      type: String,
      required: false,
      default: null
    },
    iconColor: {
      type: String,
      required: false,
      default: "primary"
    },
    backgroundColor: {
      type: String,
      required: false,
      default: "secondary"
    },
  },
  setup(props) {
    // only way I found to use the $color function declared in my plugin
    const globalProperties = getCurrentInstance().appContext.config.globalProperties;


    const contentStyle = {
      display: "flex",
      alignItems: "center",
      gap: "8px",
      backgroundColor: globalProperties.$color(props.backgroundColor)
    };

    return {
      icon: props.icon,
      label: props.label,
      color: props.iconColor,
      contentStyle
    };
  }
})
</script>

Now the issue I'm facing is that the $color call in the template works fine, but the one in the setup throws an error because this.$vuetify is undefined.

How can I access this.$vuetify in my plugin both from the template and the setup ?


Solution

  • In Vuetify 3, the $vuetify global object was dropped in favor of composables. For theme-related data, use the useTheme composable:

    useTheme().current.colors[key]
    

    Here is a playground example