zoukankan      html  css  js  c++  java
  • Vue 中使用 pxtorem 实现自适应

    一、前言

    在前端,自适应是不得不考虑的问题。

    但是实现自适应有方案也有很多种。今天介绍的是通过在 Webpack 中配置 loader 实现。

    还有一个原因,在查资料的时候,网上的一些文章对 postcss-pxtorem、px2rem-loader 用法有些混乱。

    特别是 postcss-pxtorem 是 postcss 的 plugin ,px2rem-loader 是一个独立的 loader 这一点。

    所以下面也对这一点做了对比分析。

    二、原理、选工具

    以前有项目中使用的是 px2rem-loader 这个工具库。

    工作原理是:配置一个 remUnit ,在打包过程中把所有的 px 单位通过换算:

    font-size: 16px;
    
    // 转换 16/remUnit ,remUnit =16
    font-size: 1rem;

    这样全局的 px 全部转换为了 rem。

    再配置 html 下的 font-size ,进而设置 rem 的值,达到自适应当前尺寸。

    基本原理清除了。继续搜索了一些这方面的工具库:

    postcss-pxtorem  最近一次更新 9个月前  周下载5w+  

    postcss-px2rem   最近一次更新5年前    周下载2k+

    px2rem-loader     最近一次更新3年前    周下载2k+

    通过对比后打算在项目使用第一个:postcss-pxtorem。

    下面对 postcss-pxtorem 和 px2rem-loader 做对比。

    三、下载、配置

    首先下载安装工具包:

    npm install postcss-pxtorem --save-dev

    配置:

    使用不同的脚手架,其配置方式有所不同。

    Vue-cli2

    直接在 Webpack 配置项中的 module 中添加 loader配置项:

    module: {
        rules: [
            {
                test: /.(scss|css)$/,
                loaders: [
                  'style-loader',
                  'css-loader',
                  //**************************适配配置开始
                  {
                    loader: 'postcss-loader', //放在这'style-loader','css-loader'后面,sass-loader前面
                    options: {
                      ident: 'postcss', //当引入外部的依赖包作为组件配置项时需要定义一个唯一的标识符,推荐这样写
                      plugins: [
                        pxtorem({
                          rootValue: 16, //表示根元素html的fontSize值,也可以是100,获取任意其他值
                          propList: ['*'], //设置px转换成rem的属性值,*表示所有属性的px转换为rem
                        }),
                      ],
                    },
                  },
                  //**************************适配部分结束
                  'sass-loader',
                ],
            }
        ]
    }

    因为这个是依赖 postcss 的,所以是放在 postcss-loader 配置项中的 plugins 中。

    Vue-cli3

    Vue-cli3 中没有 webpack 单独的配置问题件,需要在 vue.config.js 中配置。

    module.exports = {
    // css 配置
      css: {
        loaderOptions: {
          postcss: {
            plugins: [require('tailwindcss'), require('autoprefixer'), require('postcss-pxtorem')({
              rootValue: 16,
              propList: ['*']
            })]
          }
        }
      }
    }

    postcss 配置文件中设置(.postcssrc.js 或者 postcss.config.js):

    注意:这个适用于不同的脚手架,只是这个配置文件的名称会不一样

    module.exports = {
      plugins: {
        'autoprefixer': {
          browsers: ['Android >= 4.0', 'iOS >= 7']
        },
        'postcss-pxtorem': {
          rootValue: 16,//结果为:设计稿元素尺寸/16,比如元素宽320px,最终页面会换算成 20rem
          propList: ['*']
        }
      }
    }

    四、px2rem-loader 配置对比

    因为这个不是依赖于 postcss,所以配置上会不一样:

    这个是直接在 css 文件的 loader 里配置,和其他 loader 同级别

    Vue-cli2

    module.exports = {
      // ...
      module: {
        rules: [{
          test: /.css$/,
          use: [{
            loader: 'style-loader'
          }, {
            loader: 'css-loader'
          }, {
            loader: 'px2rem-loader',
            // options 配置
            options: {
              remUni: 75,
              remPrecision: 8
            }
          }]
        }]
      }
    }

    Vue-cli3

    module.exports = {
        chainWebpack: config => {
            config.module
                .rule('scss')
                .test(/.scss$/)
                .oneOf('vue')
                .use('px2rem-loader')
                .loader('px2rem-loader')
                .before('postcss-loader')
                .options({ remUnit: 75, remPrecision: 8 })
                .end()
        }
    }

    五、动态修改 rem 对应值

    使用上面的 loader,是把代码中的 px 全部转换为 rem。要实现自适应,需要动态的改变 html 的 font-size 才可以。

    所以要绑定对 window 绑定 onresize 事件。

    注意:为了避免其他地方也有需要根据窗口大小变化而变化的,给 onresize 绑定一个回调数组。

    /**
     * 根据屏幕变化,自动更改 html 的 font-size
     */
    
    function setRem() {
      const htmlWidth = document.body && document.body.offsetWidth
      const htmlEle = document.getElementsByTagName('html')[0]
    
      // 默认是在 1920 下 16px,那么对应比例缩放
      htmlEle.style.fontSize = htmlWidth ? (htmlWidth / 1920 * 16 + 'px') : '16px'
    }
    
    setRem()
    
    // onresize 回调数组
    window.resizeCallbackList = [setRem]
    window.onresize = () => {
      window.resizeCallbackList.map(callback => {
        callback()
      })
    }

    其他地方也需要绑定的时候,直接:

    window.resizeCallbackList.push(callback)
  • 相关阅读:
    定位IO瓶颈的方法,iowait低,IO就没有到瓶颈?
    10分钟检查自己的系统性能数据
    netperf使用指南
    如何看内核源码
    xxx
    os.path 模块
    目前中国智能语音产业的格局、现状
    NLP-python 自然语言处理01
    15本经典金融投资著作
    写给步入工作的自己
  • 原文地址:https://www.cnblogs.com/zhurong/p/14011857.html
Copyright © 2011-2022 走看看