Vue中的动态CSS类。

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

dynamic css classes in vue

问题

以下是翻译好的部分:

  1. 我正在使用vuejstailwindcss创建一个组件。我遇到了一个问题,背景和文字颜色没有应用。
  2. <template>
  3. <div :class="[isDark ? `bg-${color}-900 text-white` : `bg-${color}-200 text-${color}-900`, 'p-4 rounded-md']">
  4. <slot />
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. name: "TCard",
  10. props: {
  11. color: {
  12. type: String,
  13. default: "gray",
  14. validator: function (value) {
  15. return ["gray", "red", "yellow", "green", "blue", "indigo", "purple", "pink"].includes(value);
  16. },
  17. },
  18. isDark: {
  19. type: Boolean,
  20. default: false
  21. }
  22. },
  23. };
  24. </script>

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

英文:

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

  1. &lt;template&gt;
  2. &lt;div :class=&quot;[isDark ? `bg-${color}-900 text-white` : `bg-${color}-200 text-${color}-900`, &#39;p-4 rounded-md&#39;]&quot;&gt;
  3. &lt;slot /&gt;
  4. &lt;/div&gt;
  5. &lt;/template&gt;
  6. &lt;script&gt;
  7. export default {
  8. name: &quot;TCard&quot;,
  9. props: {
  10. color: {
  11. type: String,
  12. default: &quot;gray&quot;,
  13. validator: function (value) {
  14. 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);
  15. },
  16. },
  17. isDark: {
  18. type: Boolean,
  19. default: false
  20. }
  21. },
  22. };
  23. &lt;/script&gt;

答案1

得分: 1

根据文档

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

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

不要动态构建类名

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

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

始终使用完整的类名

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

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

  1. const MAP = {
  2. gray: {
  3. light: 'bg-gray-200 text-gray-900',
  4. dark: 'bg-gray-900 text-white',
  5. },
  6. red: {
  7. light: 'bg-red-200 text-red-900',
  8. dark: 'bg-red-900 text-white',
  9. },
  10. // …
  11. };
  12. const TCard = {
  13. props: {
  14. color: {
  15. type: String,
  16. default: "gray",
  17. validator: function (value) {
  18. return value in MAP;
  19. },
  20. },
  21. isDark: {
  22. type: Boolean,
  23. default: false
  24. }
  25. },
  26. computed: {
  27. colors() {
  28. return MAP[this.color][this.isDark ? 'dark' : 'light'];
  29. },
  30. },
  31. template: `
  32. <div :class="[colors, 'p-4 rounded-md']">
  33. <slot />
  34. </div>`
  35. };
  36. Vue.createApp({ components: { TCard }}).mount('#app');

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

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

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

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

英文:

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 -->

  1. const MAP = {
  2. gray: {
  3. light: &#39;bg-gray-200 text-gray-900&#39;,
  4. dark: &#39;bg-gray-900 text-white&#39;,
  5. },
  6. red: {
  7. light: &#39;bg-red-200 text-red-900&#39;,
  8. dark: &#39;bg-red-900 text-white&#39;,
  9. },
  10. // …
  11. };
  12. const TCard = {
  13. props: {
  14. color: {
  15. type: String,
  16. default: &quot;gray&quot;,
  17. validator: function (value) {
  18. return value in MAP;
  19. },
  20. },
  21. isDark: {
  22. type: Boolean,
  23. default: false
  24. }
  25. },
  26. computed: {
  27. colors() {
  28. return MAP[this.color][this.isDark ? &#39;dark&#39; : &#39;light&#39;];
  29. },
  30. },
  31. template: `
  32. &lt;div :class=&quot;[colors, &#39;p-4 rounded-md&#39;]&quot;&gt;
  33. &lt;slot /&gt;
  34. &lt;/div&gt;`
  35. };
  36. Vue.createApp({ components: { TCard }}).mount(&#39;#app&#39;);

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

  1. &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;
  2. &lt;script src=&quot;https://cdn.tailwindcss.com&quot;&gt;&lt;/script&gt;
  3. &lt;div id=&quot;app&quot;&gt;
  4. &lt;t-card color=&quot;red&quot;&gt;Foo&lt;/t-card&gt;
  5. &lt;t-card color=&quot;gray&quot; is-dark&gt;Bar&lt;/t-card&gt;
  6. &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:

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

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:

确定