• 在 uniapp 里面使用 unocss


    1. 安装插件

    npm i unocss @unocss/transformer-directives unocss-preset-weapp -D 这个里面加了个指令的使用, 可以根据自身需求来决定是否使用

    2. uno.config.ts 配置。

    按照这个配置基本可以解决你的问题。

    import presetWeapp from 'unocss-preset-weapp'
    import { extractorAttributify, transformerClass } from 'unocss-preset-weapp/transformer'
    import { defineConfig } from 'unocss/vite'
    import transformerDirectives from '@unocss/transformer-directives'
    
    const { presetWeappAttributify, transformerAttributify } = extractorAttributify()
    
    export default defineConfig({
      // @ts-expect-error 插件类型不匹配
      presets: [presetWeapp(), presetWeappAttributify()],
      transformers: [
        transformerDirectives({
          enforce: 'pre',
        }),
        // @ts-expect-error 插件类型不匹配
        transformerAttributify(),
        // @ts-expect-error 插件类型不匹配
        transformerClass(),
      ],
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    如果你想使用 unocss 的指令一定要看下面的, 如果你可以确定不使用那就可以不看

    你会遇到的问题:
    在配置了指令之后, 大概率会在 h5 里面遇到 rpx 无法转换为 rem。

    解决方法:
    配置 transformerDirectives({ enforce: 'pre', }),

    这是 vite 官方对这个字段的解释:
    一个 Vite 插件可以额外指定一个 enforce 属性(类似于 webpack 加载器)来调整它的应用顺序。enforce 的值可以是pre 或 post。解析后的插件将按照以下顺序排列: vite文档地址

    为什么要这样配置呢, 我们想一下, 在小程序里面使用的单位是 rpx, 在 h5 里面使用的是 rem, 为什么我们在使用 uniapp 的时候可以直接写 rpx, 因为 uniapp 的插件在内部处理了, 在编译小程序或者 h5 的时候是做了对应的处理的.

    这个时候我们就要想一下为什么添加了指令之后 rpx 就无法被转换了为 rem 了呢, 因为 unocss 里面的 transformers 执行顺序是后置与 uniapp 插件的, 所以指令生成的 rpx 是无法被 uniapp 插件处理到的

    我们来看import { extractorAttributify, transformerClass } from 'unocss-preset-weapp/transformer'这个插件的源码, 这个插件的 transformer 都配置了 enforce: 'pre', 以下是部分源码。 代码地址

     {
        name: 'transformer-weapp-class',
        idFilter,
        enforce: 'pre',
        transform(code, id) {
          let newCode = transformCode(code.toString(), options.transformRules)
    
          if (options.classTags) {
            const classNames = getClass(code.toString())
            const injectStr = Array.from(new Set(classNames.map(x => x[1]).filter(x => x).flatMap(x => x.split(' ')))).join(' ')
    
            if (vueFilter(id))
              newCode = newCode.replace('