[Vuejs]-Dynamic css classes in vue

1👍

As per the documentation:

The most important implication of how Tailwind extracts class names is that it will only find classes that exist as complete unbroken strings in your source files.

If you use string interpolation or concatenate partial class names together, Tailwind will not find them and therefore will not generate the corresponding CSS:

Don’t construct class names dynamically

<div class="text-{{ error ? 'red' : 'green' }}-600"></div>

In the example above, the strings text-red-600 and text-green-600 do not exist, so Tailwind will not generate those classes.
Instead, make sure any class names you’re using exist in full:

Always use complete class names

<div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>

You could consider using a map of classes instead like:

const MAP = {
  gray: {
    light: 'bg-gray-200 text-gray-900',
    dark: 'bg-gray-900 text-white',
  },
  red: {
    light: 'bg-red-200 text-red-900',
    dark: 'bg-red-900 text-white',
  },
  // …
};

const TCard = {
  props: {
    color: {
      type: String,
      default: "gray",
      validator: function (value) {
        return value in MAP;
      },
    },
    isDark: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    colors() {
      return MAP[this.color][this.isDark ? 'dark' : 'light'];
    },
  },
  template: `
<div :class="[colors, 'p-4 rounded-md']">
  <slot />
</div>`
};

Vue.createApp({ components: { TCard }}).mount('#app');
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.3.4/vue.global.min.js" integrity="sha512-Wbf9QOX8TxnLykSrNGmAc5mDntbpyXjOw9zgnKql3DgQ7Iyr5TCSPWpvpwDuo+jikYoSNMD9tRRH854VfPpL9A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.tailwindcss.com"></script>

<div id="app">
  <t-card color="red">Foo</t-card>
  <t-card color="gray" is-dark>Bar</t-card>
</div>

This keeps the classes you use and the template markup together. The validator can also use the MAP to verify a color you want to use exists.

Otherwise, you could use safelist in your Tailwind configuration like:


module.exports = {
  …
  safelist: [
    { pattern: /^(bg|text)-(gray|red|yellow|green|blue|indigo|purple|pink)-900$/ },
    { pattern: /^bg-(gray|red|yellow|green|blue|indigo|purple|pink)-200$/ },
  ],
  …
};

This has the disadvantage that this would be separate from your templates so you might lose/forget the link these two have. This would mean maintaining this would be more difficult to keep in sync and editing this would mean a context switch too.

👤Wongjn

Leave a comment