有没有办法强制Vue更喜欢继承的类?

问题描述 投票:0回答:3

我有一个组件,我希望 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>
html css vue.js vuejs3 tailwind-css
3个回答
1
投票

我终于设法使用第 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>

0
投票

在我看来,你有两个选择:

  1. 对于 alignmentcolor 和 ...,您可以使用默认的类名值定义 props:
props: {
  alignment: 'start',
  // other props
},

并将这些道具绑定到 CSS 类并在那里使用它们。

  1. 您可以使用 vue 指令:
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>


0
投票

我创建了一个专门用于解决此问题的 npm 包:

https://www.npmjs.com/package/tailwind-merge-vue-directive

它本质上就是按照人们上面的建议做的。

© www.soinside.com 2019 - 2024. All rights reserved.