我有一个组件,我希望 Vue 忽略已经存在的类并使用继承的类。但前提是该类与继承的类具有相同的类型。这是我的意思的一个例子:
我有一个像这样的按钮组件
我的按钮.vue
<button class="text-sm font-roboto justify-center text-red-500">
<slot></slot>
</button>
然后在我的项目中我想使用
MyButton
组件,但我想用我自己的类覆盖 justify-center
和 text-red-500
类,例如这样:
<MyButton class="justify-start text-gray-100">click me</MyButton>
结果就是这个渲染的按钮:
<button class="text-sm font-roboto justify-center text-red-500 justify-start text-gray-100">
click me
</button>
问题是 HTML 优先考虑
justify-center
类,而 justify-start
类被忽略。我希望 Vue 足够聪明,能够理解 Tailwind 类,如果它发现原来有 justify-center
,现在我传入 justify-start
,那么它应该删除 justify-center
并添加 justify-start
。
我也希望它为所有 Tailwind 课程执行此操作。如果它发现原来有一个
text-....
类,那么它应该删除它并用继承的类替换它。 fonts
和 colors
和 shadows
等也一样。
所以结果会是这样的:
<button class="text-sm font-roboto justify-start text-gray-100">
click me
</button>
我终于设法使用第 3 方库来做到这一点
tailwind-merge
<template>
<button :class="buttonClass">
<slot></slot>
<i class="text-base text-gray-400 font-normal">
class="{{ buttonClass }}"</i>
</button>
</template>
<script setup lang="ts">
import { computed, useAttrs } from 'vue'
import { twMerge } from 'tailwind-merge'
const attrs = useAttrs()
const buttonClass = computed(() => {
return twMerge('font-bold text-3xl justify-center text-red-500 ', attrs.class)
})
</script>
<script lang="ts">
export default {
inheritAttrs: false
}
</script>
在我看来,你有两个选择:
props: {
alignment: 'start',
// other props
},
并将这些道具绑定到 CSS 类并在那里使用它们。
Vue.directive('tailwind', {
bind: function(el, binding, vnode) {
let currentClasses = el.classList;
for (let i = 0; i < currentClasses.length; i++) {
let className = currentClasses[i];
if (className.startsWith('text-') || className.startsWith('justify-') || className.startsWith('font-')) {
el.classList.remove(className);
}
}
},
update: function(el, binding, vnode) {
let newClasses = binding.value.split(' ');
for (let i = 0; i < newClasses.length; i++) {
let className = newClasses[i];
if (className.startsWith('text-') || className.startsWith('justify-') || className.startsWith('font-')) {
el.classList.add(className);
}
}
}
});
你可以这样使用它:
<button v-tailwind="class" class="text-sm font-roboto justify-center text-red-500">
<slot></slot>
</button>
<MyButton class="justify-start text-gray-100">click me</MyButton>
我创建了一个专门用于解决此问题的 npm 包:
https://www.npmjs.com/package/tailwind-merge-vue-directive
它本质上就是按照人们上面的建议做的。