Vue中的动态CSS类。

huangapple go评论142阅读模式
英文:

dynamic css classes in vue

问题

以下是翻译好的部分:

我正在使用vuejs和tailwindcss创建一个组件。我遇到了一个问题,背景和文字颜色没有应用。

<template>
  <div :class="[isDark ? `bg-${color}-900 text-white` : `bg-${color}-200 text-${color}-900`, 'p-4 rounded-md']">
    <slot />
  </div>
</template>

<script>
export default {
  name: "TCard",
  props: {
    color: {
      type: String,
      default: "gray",
      validator: function (value) {
        return ["gray", "red", "yellow", "green", "blue", "indigo", "purple", "pink"].includes(value);
      },
    },
    isDark: {
      type: Boolean,
      default: false
    }
  },
};
</script>

请注意,我已经将代码部分保留在原文中,只翻译了您提供的内容。

英文:

I'm creating a component using vuejs and tailwindcss. I'm encountering an issue where the background and text colors are not applied.

&lt;template&gt;
  &lt;div :class=&quot;[isDark ? `bg-${color}-900 text-white` : `bg-${color}-200 text-${color}-900`, &#39;p-4 rounded-md&#39;]&quot;&gt;
    &lt;slot /&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  name: &quot;TCard&quot;,
  props: {
    color: {
      type: String,
      default: &quot;gray&quot;,
      validator: function (value) {
        return [&quot;gray&quot;, &quot;red&quot;, &quot;yellow&quot;, &quot;green&quot;, &quot;blue&quot;, &quot;indigo&quot;, &quot;purple&quot;, &quot;pink&quot;].includes(value);
      },
    },
    isDark: {
      type: Boolean,
      default: false
    }
  },
};
&lt;/script&gt;

答案1

得分: 1

根据文档

Tailwind提取类名的最重要影响是它只会找到在源文件中作为_完整未中断的字符串_存在的类。

如果您使用字符串插值或将部分类名连接在一起,Tailwind将无法找到它们,因此不会生成相应的CSS:

不要动态构建类名

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

在上面的示例中,字符串text-red-600text-green-600不存在,因此Tailwind不会生成这些类。
相反,请确保您使用的任何类名都完整存在:

始终使用完整的类名

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

您可以考虑使用类映射,如下所示:

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');

这将保持您使用的类和模板标记在一起。validator 也可以使用 MAP 来验证您想要使用的颜色是否存在。

否则,您可以在Tailwind配置中使用safelist,如下所示:

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$/ },
  ],
  
};

这种方法的缺点是它会与模板分开,因此您可能会失去/忘记这两者之间的关联。这意味着维护这个会更难以保持同步,编辑这个也会导致上下文切换。

英文:

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
>
> vue
&gt; &lt;div class=&quot;text-{{ error ? &#39;red&#39; : &#39;green&#39; }}-600&quot;&gt;&lt;/div&gt;
&gt;

> 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
>
> vue
&gt; &lt;div class=&quot;{{ error ? &#39;text-red-600&#39; : &#39;text-green-600&#39; }}&quot;&gt;&lt;/div&gt;
&gt;

You could consider using a map of classes instead like:

<!-- begin snippet: js hide: false console: false babel: false -->

<!-- language: lang-js -->

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

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

Vue.createApp({ components: { TCard }}).mount(&#39;#app&#39;);

<!-- language: lang-html -->

&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/vue/3.3.4/vue.global.min.js&quot; integrity=&quot;sha512-Wbf9QOX8TxnLykSrNGmAc5mDntbpyXjOw9zgnKql3DgQ7Iyr5TCSPWpvpwDuo+jikYoSNMD9tRRH854VfPpL9A==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://cdn.tailwindcss.com&quot;&gt;&lt;/script&gt;

&lt;div id=&quot;app&quot;&gt;
  &lt;t-card color=&quot;red&quot;&gt;Foo&lt;/t-card&gt;
  &lt;t-card color=&quot;gray&quot; is-dark&gt;Bar&lt;/t-card&gt;
&lt;/div&gt;

<!-- end snippet -->

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.

huangapple
  • 本文由 发表于 2023年7月7日 06:58:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76632990.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定