vue3 + vite + ts 设置自适应px转vw

1,387 阅读1分钟

设置vite.config.ts 需要安装postcss-px-to-viewport 插件

然后在根目录下创建style-px-to-vw.js或者ts文件

style-px-to-vw.js代码如下

// 默认参数
let defaultsProp = {
  unitToConvert: "px",
  viewportWidth: 3840,
  unitPrecision: 5,
  viewportUnit: "vw",
  fontViewportUnit: "vw",
  minPixelValue: 1,
};
function toFixed(number, precision) {
  var multiplier = Math.pow(10, precision + 1),
    wholeNumber = Math.floor(number * multiplier);
  return (Math.round(wholeNumber / 10) * 10) / multiplier;
}

function createPxReplace(
  viewportSize,
  minPixelValue,
  unitPrecision,
  viewportUnit
) {
  return function ($0, $1) {
    if (!$1) return;
    var pixels = parseFloat($1);
    if (pixels <= minPixelValue) return;
    return toFixed((pixels / viewportSize) * 100, unitPrecision) + viewportUnit;
  };
}
const templateReg = /<template>([\s\S]+)<\/template>/gi;
const pxGlobalReg = /(\d+)px/gi;

// 生成插件的工厂方法
const pluginGenerator = (customOptions = defaultsProp) => {
  // 返回插件
  return {
    // 插件名称
    name: "postcss-px-to-viewport",

    // transform 钩子
    async transform(code, id) {
      let _source = "";
      if (/.vue$/.test(id)) {
        let _source = "";
        if (templateReg.test(code)) {
          _source = code.match(templateReg)[0];
        }
        if (pxGlobalReg.test(_source)) {
          let $_source = _source.replace(
            pxGlobalReg,
            createPxReplace(
              customOptions.viewportWidth,
              customOptions.minPixelValue,
              customOptions.unitPrecision,
              customOptions.viewportUnit
            )
          );

          code = code.replace(_source, $_source);
          // console.log(code);
        }
      }
      return { code };
    },
  };
};

export default pluginGenerator;

vite.config.ts中的设置

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve, join } from 'path';
// import pxtovw from 'postcss-px-to-viewport'
// import  stylePxToVw  from './style-px-to-vw';

// https://vitejs.dev/config/
export default defineConfig({
  // base: '/sgdvp-build/', // 打包时添加前缀
  base: './', 
  plugins: [vue()],
  resolve: {
    alias: {
      '@': resolve(join(__dirname, 'src'))
    }
  }
  // css: {
  //   postcss: {
  //     plugins: [
  //       pxtovw({
  //         viewportWidth: 3840,
  //         viewportHeight: 2160,
  //         unitPrecision: 3,               // (Number) The decimal numbers to allow the REM units to grow to. 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
  //         virwportUnit: 'vw',             // (String) Expected units. 指定需要转换成的视窗单位,建议使用vw
  //         selectorBlackList: ['.ignore'], // (Array) The selectors to ignore and leave as px. 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
  //         minPixelVlaue: 1,               // (Number) Set the minimum pixel value to replace. 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
  //         mediaQuery: false,
  //       })
  //     ]
  //   }
  // },
});