在 HBuilderX 中使用 tailwindcss

【uniapp】---- 在 HBuilderX 中使用 tailwindcss

1. 前言

接手了一个uniapp的微信小程序项目,因为在上一个 taro 的项目中使用的 tailwindcss,感觉比较方便,又不想动项目中原来的代码,因此就配置 tailwindcss,在新创建的子包中使用。

2. 分析

vue2 版本的 uni-app 内置的 webpack 版本为 4 , postcss 版本为 7, 所以还是只能使用 @tailwindcss/postcss7-compat 版本。

3. package.json

新建一个vue2 uni-app项目,然后我们 npm init -y 在项目根目录创建一个 package.json,并安装依赖。

3.1 添加依赖

perl 复制代码
    "autoprefixer": "9",
    "postcss": "7",
    "postcss-rem-to-responsive-pixel": "^5.1.3",
    "tailwindcss": "npm:@tailwindcss/postcss7-compat",
    "weapp-tailwindcss-webpack-plugin": "^1.6.8",
    "webpack": "npm:webpack@webpack-4"

3.2 原项目配置结果

4. vue.config.js

在 vue.config.js 文件,注册 weapp-tailwindcss-webpack-plugin。

4.1 注册

arduino 复制代码
// 为了 tailwindcss jit 开发时的热更新
if (process.env.NODE_ENV === "development") {
  process.env.TAILWIND_MODE = "watch";
}

const {
  UniAppWeappTailwindcssWebpackPluginV4,
} = require("weapp-tailwindcss-webpack-plugin");

/**
 * @type {import('@vue/cli-service').ProjectOptions}
 */
const config = {
  //....
  configureWebpack: {
    plugins: [new UniAppWeappTailwindcssWebpackPluginV4()],
  },
  //....
};

module.exports = config;

4.2 注册结果

5. tailwind.config.js

5.1 配置 tailwind.config.js

css 复制代码
const path = require("path");
const resolve = (p) => {
  return path.resolve(__dirname, p);
};

/** @type {import('@types/tailwindcss/tailwind-config').TailwindConfig} */
module.exports = {
  mode: "jit",
  purge: {
    content: [
      resolve("./index.html"),
      resolve("./pages/**/*.{vue,js,ts,jsx,tsx,wxml}"),
    ],
  },
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {},
  plugins: [],
  corePlugins: {
    preflight: false,
  },
};

content 也必须为绝对路径。

5.2 配置结果

6. postcss.config.js

6.1 配置 postcss.config.js

lua 复制代码
const path = require("path");

module.exports = {
  plugins: [
    require("autoprefixer")({
      remove: process.env.UNI_PLATFORM !== "h5",
    }),
    require("tailwindcss")({
      config: path.resolve(__dirname, "./tailwind.config.js"),
    }),
    // rem 转 rpx
    require("postcss-rem-to-responsive-pixel/postcss7")({
      rootValue: 32,
      propList: ["*"],
      transformUnit: "rpx",
    }),
  ],
};

这里特别注意,在声明所有路径时,必须声明为绝对路径!!! 因为 hbuilderx 有这样一个读取配置的策略:如果目标目录是相对路径,就会读取 '\HBuilderX\plugins\uniapp-cli' 目录下的文件,这直接导致配置找不到,导致项目无法启动。

6.2 配置结果

7. 引入 tailwindcss

在 App.vue 引入即可:

7.1 App.vue 引入 tailwindcss

xml 复制代码
<style lang="scss">
/*每个页面公共css */
@import "tailwindcss/base";
@import "tailwindcss/utilities";
</style>

7.2 引入结果

8. 运行结果

8.1 测试代码

8.2 运行效果

9. 总结

  1. 由于这是接手的一个比较老的项目,使用的是 vue2,所以这里是按照 vue2版本配置的 tailwindcss。
  2. 参考 在 HBuilderX 中使用 tailwindcss
  3. 如果只到这里的话,就是转载了大佬的文章,必定我也没有写自己的东西,所以接下来就说说这么配置的还需要的优化。

10. 优化

  1. m-* 、p-、size- 等都不支持 [22rpx_30rpx] 这种拼接的值,这也就是导致在设置 border 这些的时候如果使用 tailwindcss 会比较麻烦,注意我这里说的是按照上边这样配置后出现的问题,不是说 tailwindcss 本身存在这种问题,因此为了解决这个问题,需要我们自己写一些 class。
  2. 就是限制显示多少行,需要单独安装插件,不能直接使用,tailwindcss-line-clamp,当然如果没有第一步的问题,那么我也就直接安装 tailwindcss-line-clamp 来解决问题,但是我这里第一步需要自己搞,所以就一起配置了。

11. 解决第一个问题

11.1 引入 tailwindcss/plugin

ini 复制代码
const plugin = require('tailwindcss/plugin');

11.2 修改 plugins 配置

  1. 为了不和 size-* 冲突,因此此处同时设置宽高使用的是 wh-*;
  2. 由于 wh-[20rpx_50rpx] 中的单位 rpx 占位比较多,因此新增 value = value.split("").map(item => ${item}rpx).join(""); 逻辑,兼容 wh-[20_50] 的实现效果一样,当然这只是在我自己的项目中,可以这样缩写,比如设置边框,圆角我使用的是 b-* 、 bd-* ,但是不建议这么些,主要是意义不明确,不利于其他人使用,因此这里的设置基本都是为了方便我自己开发使用,你可以根据原理和自己的习惯来配置,方便更加快速的开发。
javascript 复制代码
plugin(({ matchUtilities, theme }) => {
  matchUtilities(
    {
      'wh': (value) => {
        if(!value.includes("rpx")){
          value = value.split("_").map(item => `${item}rpx`).join("_");
        }
        const [width, height] = value.split("_");
        return { width, height: height || value }
      },
      'bb': (value) => {
        value = value.replace(/_/g," ");
        return {
          "border-bottom": value
        }
      },
      'b': (value) => {
        value = value.replace(/_/g," ");
        return {
          "border": value
        }
      },
      'bt': (value) => {
        value = value.replace(/_/g," ");
        return {
          "border-top": value
        }
      },
      'bd': (value) => {
        if(!value.includes("rpx")){
          value = value.split("_").map(item => `${item}rpx`).join("_");
        }
        value = value.replace(/_/g," ");
        return {
          "border-radius": value
        }
      },
      'tc': (value) => {
        const [size, color] = value.split("_");
        return {
          "font-size": size,
          color
        }
      },
      'rm': (value) => {
        if(!value.includes("rpx")){
          value = value.split("_").map(item => `${item}rpx`).join("_");
        }
        const margin = value.replace(/_/g," ");
        return {margin}
      },
      'rp': (value) => {
        if(!value.includes("rpx")){
          value = value.split("_").map(item => `${item}rpx`).join("_");
        }
        const padding = value.replace(/_/g," ");
        return {padding}
      },
      'fw': (value) => {
        return {"font-weight": value}
      },
    },
    {
      values: theme('spacing'), // 使用 Tailwind 默认的 spacing 值
      type: 'any', // 支持任意值
    }
  );
})

11.3 修改后的完整配置

javascript 复制代码
const plugin = require('tailwindcss/plugin');
const path = require("path");
const resolve = (p) => {
  return path.resolve(__dirname, p);
};

/** @type {import('@types/tailwindcss/tailwind-config').TailwindConfig} */
module.exports = {
  mode: "jit",
  purge: {
    content: [
      resolve("./index.html"),
      resolve("./pages/**/*.{vue,js,ts,jsx,tsx,wxml}"),
    ],
  },
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {},
  plugins: [
   plugin(({ matchUtilities, theme }) => {
    matchUtilities(
      {
        'wh': (value) => {
          if(!value.includes("rpx")){
            value = value.split("_").map(item => `${item}rpx`).join("_");
          }
          const [width, height] = value.split("_");
          return { width, height: height || value }
        },
        'bb': (value) => {
          value = value.replace(/_/g," ");
          return {
            "border-bottom": value
          }
        },
        'b': (value) => {
          value = value.replace(/_/g," ");
          return {
            "border": value
          }
        },
        'bt': (value) => {
          value = value.replace(/_/g," ");
          return {
            "border-top": value
          }
        },
        'bd': (value) => {
          if(!value.includes("rpx")){
            value = value.split("_").map(item => `${item}rpx`).join("_");
          }
          value = value.replace(/_/g," ");
          return {
            "border-radius": value
          }
        },
        'tc': (value) => {
          const [size, color] = value.split("_");
          return {
            "font-size": size,
            color
          }
        },
        'rm': (value) => {
          if(!value.includes("rpx")){
            value = value.split("_").map(item => `${item}rpx`).join("_");
          }
          const margin = value.replace(/_/g," ");
          return {margin}
        },
        'rp': (value) => {
          if(!value.includes("rpx")){
            value = value.split("_").map(item => `${item}rpx`).join("_");
          }
          const padding = value.replace(/_/g," ");
          return {padding}
        },
        'fw': (value) => {
          return {"font-weight": value}
        },
      },
      {
        values: theme('spacing'), // 使用 Tailwind 默认的 spacing 值
        type: 'any', // 支持任意值
      }
    );
   })
  ],
  corePlugins: {
    preflight: false,
  },
};

11.4 使用

css 复制代码
<view class="bg-[#FFF0DF] tc-[24rpx_#EC8600] h-[42rpx] cc rp-[0_12] bd-[4] flex-none">招人</view>

11.5 效果

12. 解决限制行数

12.1 配置 theme

css 复制代码
theme: {
  extend: {
    lineClamp: {
      1: '1',
      2: '2',
      3: '3',
      4: '4',
      5: '5',
      6: '6',
    }
  },
}

12.2 plugins 配置

注意:values 的配置,就是第一步中的 theme('lineClamp')!!!

javascript 复制代码
plugin(({ matchUtilities, theme }) => {
  matchUtilities({
    'limit': (value) => {
      return {
        "overflow": "hidden",
        "text-overflow": "ellipsis",
        "display": "box",
        "display": "-webkit-box",
        "-webkit-line-clamp": `${value}`,
        "-webkit-box-orient": "vertical"
      }
    }
  },{
    values: theme('lineClamp'), // 使用 Tailwind 默认的 spacing 值
    type: 'any', // 支持任意值
  });
})

12.3 两个问题的完整配置

javascript 复制代码
const path = require("path");
const resolve = (p) => {
  return path.resolve(__dirname, p);
};
const plugin = require('tailwindcss/plugin');

/** @type {import('@types/tailwindcss/tailwind-config').TailwindConfig} */
module.exports = {
  mode: "jit",
  purge: {
    content: [
      resolve("./index.html"),
      resolve("./pages/**/*.{vue,js,ts,jsx,tsx,wxml}"),
    ],
  },
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {
      lineClamp: {
        1: '1',
        2: '2',
        3: '3',
        4: '4',
        5: '5',
        6: '6',
      }
    },
  },
  variants: {},
  plugins: [
    plugin(({ matchUtilities, theme }) => {
      matchUtilities(
        {
          'wh': (value) => {
            if(!value.includes("rpx")){
              value = value.split("_").map(item => `${item}rpx`).join("_");
            }
            const [width, height] = value.split("_");
            return { width, height: height || value }
          },
          'bb': (value) => {
            value = value.replace(/_/g," ");
            return {
              "border-bottom": value
            }
          },
          'b': (value) => {
            value = value.replace(/_/g," ");
            return {
              "border": value
            }
          },
          'bt': (value) => {
            value = value.replace(/_/g," ");
            return {
              "border-top": value
            }
          },
          'bd': (value) => {
            if(!value.includes("rpx")){
              value = value.split("_").map(item => `${item}rpx`).join("_");
            }
            value = value.replace(/_/g," ");
            return {
              "border-radius": value
            }
          },
          'tc': (value) => {
            const [size, color] = value.split("_");
            return {
              "font-size": size,
              color
            }
          },
          'rm': (value) => {
            if(!value.includes("rpx")){
              value = value.split("_").map(item => `${item}rpx`).join("_");
            }
            const margin = value.replace(/_/g," ");
            return {margin}
          },
          'rp': (value) => {
            if(!value.includes("rpx")){
              value = value.split("_").map(item => `${item}rpx`).join("_");
            }
            const padding = value.replace(/_/g," ");
            return {padding}
          },
          'fw': (value) => {
            return {"font-weight": value}
          },
        },
        {
          values: theme('spacing'), // 使用 Tailwind 默认的 spacing 值
          type: 'any', // 支持任意值
        }
      );
    }),
    plugin(({ matchUtilities, theme }) => {
      matchUtilities({
        'limit': (value) => {
          return {
            "overflow": "hidden",
            "text-overflow": "ellipsis",
            "display": "box",
            "display": "-webkit-box",
            "-webkit-line-clamp": `${value}`,
            "-webkit-box-orient": "vertical"
          }
        },
      },{
        values: theme('lineClamp'), // 使用 Tailwind 默认的 spacing 值
        type: 'any', // 支持任意值
      });
    }),
  ],
  corePlugins: {
    preflight: false,
  },
};

12.4 效果

13. 总结

  1. 解决办法不一定是最好的,但是是我当前使用比较快的解决办法,也解决了我的问题;
  2. 真心不建议像我这么简写,除了我自己知道是干啥的,其他开发根本就看不懂,但是没办法,我又是比较懒的人,就将我常用的样式这么简化了,按照自己的需求来,特别是多人开发的大项目,千万不要我这么搞,我这个就我自己玩玩没事,也没人找我,你如果多人开发,小心项目经历拿砍刀来找你。
相关推荐
Ratten3 小时前
uniapp的H5 在 UC 浏览器中返回上一页失效的解决方案
uni-app
Ratten3 小时前
uniapp 的 H5和微信小程序上传 base64 图片
uni-app
Ratten3 小时前
使用 uniapp 扩展组件 uni-file-picker 实现视频和图片都可以预览展示
uni-app
江湖行骗老中医16 小时前
uniapp 引入使用u-view 完整步骤,u-view 样式不生效
uni-app
雪芽蓝域zzs16 小时前
uniapp 页面favicon.ico文件不存在提示404问题解决
uni-app
一嘴一个橘子16 小时前
uniapp 顶部tab + 占满剩余高度的内容区域swiper
javascript·uni-app
睡美人的小仙女12716 小时前
在 UniApp 中,实现下拉刷新
uni-app
iOS阿玮20 小时前
江湖传闻谷歌比苹果严格多了,那么到底有多狠?
uni-app·app·apple
!win !1 天前
uni-app支付宝端彻底禁掉下拉刷新效果
前端·小程序·uni-app