Talk about using flexible and px2rem loader in Vue cli

Keywords: Javascript npm Webpack less sass

1. Download lib flexible

npm i lib-flexible --save
//or
yarn add lib-flexible

2. Introduce lib flexible in the project. Generally, introduce lib flexible in (main.js)

import 'lib-flexible/flexible'

3. Set meta tag (as appropriate)

<meta name="viewport" content="width=device-width, initial-scale=1.0">

4. Install px2rem loader

npm install px2rem-loader   --save
//or
yarn add px2rem-loader

5. Configure px2rem loader in webpack

1. Find util.js in the project build file and add px2rem loader to cssLoaders,
2. remUnit under px2rem loader depends on the design draft
The details are as follows:

exports.cssLoaders = function (options) {
  options = options || {}

  const cssLoader = {
    loader: 'css-loader',
    options: {
      minimize: process.env.NODE_ENV === 'production',
      sourceMap: options.sourceMap
    }
  }
  //rem compilation (New px2)
  const px2remLoader = {
    loader: 'px2rem-loader',
    options: {
      remUnit: 75 // Because the design is 750
    }
  }

  function generateLoaders (loader, loaderOptions) {
    var loaders = [cssLoader,px2remLoader]//Add to loader
    //Omit...
  }
}

6. Used in the project

Suppose the width and font size of the design draft are 200px and 50px respectively
Specific code: (write according to the design draft)

.demo{
    width: 200px;
    font-size: 50px;
}

7. Using flexible alone, you can directly add a rem.js file, as follows:

1. Coordinate with less, sass and stylus to do px conversion rem
2. For details, please refer to css compilation

/*
** Mobile adaptive scheme
*/
export const setViewport = (()=>{//This is for individual use
    const win = window
    const lib = window.lib || (window.lib = {})
//; (function(win, lib) {/ / this is for direct use
    let doc = win.document;
    let docEl = doc.documentElement;
    let metaEl = doc.querySelector('meta[name="viewport"]');
    let flexibleEl = doc.querySelector('meta[name="flexible"]');
    let dpr = 0;
    let scale = 0;
    let tid;
    let flexible = lib.flexible || (lib.flexible = {});
    
    if (metaEl) {
        //console.warn('scaling will be set according to the existing meta label ');
        let match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
        if (match) {
            scale = parseFloat(match[1]);
            dpr = parseInt(1 / scale);
        }
    } else if (flexibleEl) {
        let content = flexibleEl.getAttribute('content');
        if (content) {
            let initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
            let maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
            if (initialDpr) {
                dpr = parseFloat(initialDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));
            }
            if (maximumDpr) {
                dpr = parseFloat(maximumDpr[1]);
                scale = parseFloat((1 / dpr).toFixed(2));
            }
        }
    }

    if (!dpr && !scale) {
        //let isAndroid = win.navigator.appVersion.match(/android/gi);
        let isIPhone = win.navigator.appVersion.match(/iphone/gi);
        let devicePixelRatio = win.devicePixelRatio;
        if (isIPhone) {
            // Under iOS, for 2 and 3 screens, use 2-fold scheme, and for the rest, use 1-fold scheme
            if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
                dpr = 3;
            } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
                dpr = 2;
            } else {
                dpr = 1;
            }
        } else {
            // Under other equipment, the scheme of 1 times is still used
            dpr = 1;
        }
        scale = 1 / dpr;
    }

    docEl.setAttribute('data-dpr', dpr);
    if (!metaEl) {
        metaEl = doc.createElement('meta');
        metaEl.setAttribute('name', 'viewport');
        metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
        if (docEl.firstElementChild) {
            docEl.firstElementChild.appendChild(metaEl);
        } else {
            let wrap = doc.createElement('div');
            wrap.appendChild(metaEl);
            doc.write(wrap.innerHTML);
        }
    }

    function refreshRem(){
        let width = docEl.getBoundingClientRect().width;
        if (width / dpr > 540) {
            width = 540 * dpr;
        }
        let rem = width / 10;
        docEl.style.fontSize = rem + 'px';
        flexible.rem = win.rem = rem;
    }

    win.addEventListener('resize', function() {
        clearTimeout(tid);
        tid = setTimeout(refreshRem, 300);
    }, false);
    win.addEventListener('pageshow', function(e) {
        if (e.persisted) {
            clearTimeout(tid);
            tid = setTimeout(refreshRem, 300);
        }
    }, false);

    if (doc.readyState === 'complete') {
        doc.body.style.fontSize = 12 * dpr + 'px';
    } else {
        doc.addEventListener('DOMContentLoaded', function() {
            doc.body.style.fontSize = 12 * dpr + 'px';
        }, false);
    }

    refreshRem();

    flexible.dpr = win.dpr = dpr;
    flexible.refreshRem = refreshRem;
    flexible.rem2px = function(d) {
        let val = parseFloat(d) * this.rem;
        if (typeof d === 'string' && d.match(/rem$/)) {
            val += 'px';
        }
        return val;
    };
    flexible.px2rem = function(d) {
        let val = parseFloat(d) / this.rem;
        if (typeof d === 'string' && d.match(/px$/)) {
            val += 'rem';
        }
        return val;
    };

});
//})(window, window.lib || (window.lib = {}));

Posted by pdpullmn612 on Wed, 04 Dec 2019 20:37:07 -0800