Subscribe on changes!

Vue interface missing $style

avatar
Sep 2nd 2020

What problem does this feature solve?

When trying to access the styles in setup(), you need access to $style. $style is present but not defined on the ComponentInstance that is returned from getCurrentInstance(). For typescript users, this causes us to have to cast the ComponentInstance to an any to get at $style.

You might need $style in setup for a number of reasons, once use case that I ran across was that I needed a computed to supply some class values to my template, so my element already had a :class on it but then I also needed to add a static class to the element and since I was using a style module, I had to use :class to add that static class. This meant that I had to add the static class to the output of the computed, which meant that I needed to access $style from setup.

What does the proposed API look like?

In vue.d.ts the interface Vue needs to have: $style: object[]

I think object[] is the right declaration, but I am not positive. I also am not sure if it needs to be readonly like the other $ accessors. I think we are allowed to modify it in code right?

avatar
Sep 2nd 2020

If you need to access it inside of the setup you should be using useCssModule

avatar
Sep 2nd 2020

ah, ok. I didn't know about that. Thanks. Unfortunately, I am stuck on v2 using the composition api plugin until Vuetify ports to v3. I guess I will keep using the any cast or mock up an equivalent to useCssModule for my code so I am closer to being ready to port to v3 when Vuetify pulls the trigger.

avatar
Sep 2nd 2020

There's an equivalent useCssModule for the @vue/composition-api plugin

avatar
Sep 2nd 2020

Can you provide a boiled down reproduction? At this state, this isn't clear. Is it a Vue 2 or Vue 3 issue?

avatar
Sep 2nd 2020

@posva Sure..

export default defineComponent({
  name: 'SCard',
  setup(props) {
    const { $style, $scopedSlots } = getCurrentInstance()!;

    const sheetClasses = computed((): Dictionary<boolean> => {
        const classes: Dictionary<boolean> = {};
        classes[$style.heading] = true;
        if ($scopedSlots.image === undefined) {
          classes['pa-5'] = true;
        }
        return classes;
      }
    );
   
   return { sheetClasses };
});

The on the line: const { $style, $scopedSlots } = getCurrentInstance()!;

$style is an error because getCurrentInstance's ComponentInstance doesn't have $style, but it does have $scopedSlots defined as members. However, if you stop there in the debugger, $style does exist on the instance because the style is a module. (not shown in the code above).

However based on what @pikax suggested, I have changed my code to be:

export default defineComponent({
  name: 'SCard',
  setup(props) {
    const { $scopedSlots } = getCurrentInstance()!;
    const $style = useCSSModule();

    const sheetClasses = computed((): Dictionary<boolean> => {
        const classes: Dictionary<boolean> = {};
        classes[$style.heading] = true;
        if ($scopedSlots.image === undefined) {
          classes['pa-5'] = true;
        }
        return classes;
      }
    );
   
   return { sheetClasses };
});

And that works great.

At this point since we should be using useCSSModule, I wouldn't complain if you decide not to add $style to the Vue interface. If it was there, I wouldn't have learned that I should be using useCSSModule.

avatar
Sep 2nd 2020

Okay, closing then. This is also vue 3 repository. BTW you should access slots on the second argument of setup, the context (https://composition-api.vuejs.org/api.html#setup)