UnoCSS不支持动态类及替换方案

1,994 阅读1分钟

这篇笔记主要记录

  1. UnoCss不支持动态类dynamic class的原因
  2. 替换方法去写动态样式

今天开发遇到了下图中进度条长度要根据数据动态显示,于是想当然的就写了动态类,看下代码

image.png

 <div
      v-for="(item, itemIndex) in list"
      :key="itemIndex"
      class="flex justify-around w-full items-center h-[122px]"
      :class="itemIndex !== 0 ? 'mt-[112px]' : ''"
    >
    <!--左边标签  和笔记知识点无关 可以不看 -->
      <div class="text-[80px] text-white shrink-0 w-[750px] text-right mr-[44px]">
        {{ item.label }}
      </div>
      
       <!--中间进度 下面的动态样式类 -->
      <div
        class="w-[2000px] shrink-0 h-[122px] bg-[#172D4E] rounded-[16px] border-2 border-solid border-[#58BBFF] flex justify-start items-center px-[25px]"
      >
        <div
          class="h-[56px] rounded-[28px] progress"
          :class="
            item.key !== 'WORK_ALERT_TOTAL'
              ? `w-[${((Number(item.percent.replace('%', '')) / 100) * 1950).toFixed(0)}px]`
              : `w-[1950px]`
          "
        ></div>
      </div>
      
      <!--右侧百分比 和笔记知识点无关 可以不看-->
      <div class="w-[600px] flex ml-[70px] shrink-0">
        <div class="text-[rgba(160,249,255,1)] text-[96px] w-[298px]">
          {{ item.value }}<span class="text-[72px]">{{ item.unit }}</span>
        </div>
        <div class="text-[rgba(112,184,255,1)] text-[96px]" v-if="item.key !== 'WORK_ALERT_TOTAL'">
          {{ item.percent }}
        </div>
      </div>
    </div>

进度条计算方法就是((Number(item.percent.replace('%', '')) / 100) * 1950).toFixed(0)}px 它的百分比*它的DiV的宽度,就是说如果百分比是85%,div宽度是1950px, 那个进度条长度就是85%*1950px

image.png 可以看到动态样式类正确渲染了,但是不会生成样式。

为什么UnoCSS不支持动态样式呢

因为UnoCSS在build time时, 会对你的代码做一次静态分析,然后生成对应的样式文件,而请求数据,根据用户操作生成不同的UI就是运行时操作,这时候UnoCSS是没法生效的。这么说肯定有小伙伴有疑问了,我这是开发阶段,没有打包啊

因为我们在用vite热模块进行更新的时候,这时候UnoCSS的能力和build time是一样的,还是没法根据动态类生成样式。

顺便说一下tailwindcss也是不可以用动态构建样式类名的

image.png

替换方法去写动态样式

问题总得解决,既然不能用动态样式类,那就试试动态内联样式,看代码

<script setup>
  const getStyle = item => {
    return {
      width:
        item.key !== 'WORK_ALERT_TOTAL'
          ? `${((Number(item.percent.replace('%', '')) / 100) * 1950).toFixed(0)}px`
          : '1950px',
    }
  }
</script>

<template>
 ...
   <div
        class="w-[2000px] shrink-0 h-[122px] bg-[#172D4E] rounded-[16px] border-2 border-solid border-[#58BBFF] flex justify-start items-center px-[25px]"
      >
        <div class="h-[56px] rounded-[28px] progress" :style="getStyle(item)"></div>
      </div>
 ...
</template>

看下效果,正常渲染。

image.png