英文:
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.
<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>
答案1
得分: 1
根据文档:
Tailwind提取类名的最重要影响是它只会找到在源文件中作为_完整未中断的字符串_存在的类。
如果您使用字符串插值或将部分类名连接在一起,Tailwind将无法找到它们,因此不会生成相应的CSS:
不要动态构建类名
<div class="text-{{ error ? 'red' : 'green' }}-600"></div>
在上面的示例中,字符串
text-red-600
和text-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
> <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
>
> vue
> <div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>
>
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: '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');
<!-- language: lang-html -->
<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>
<!-- 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论