vue + (webpack/ vite) pc 端页面适配

关于vue 在pc端的页面适配做一个比较详细的汇总

因为之前自己用的都是vue2 + webpack 所以对于这个的适配比较熟练  后来又用到了vue3+ vite, 两者关于pc端页面适配的流程差别不大,下面做一个汇总 (萌新笔记)

1. vue2 + webpake

首先需要安装两个插件 (也可以只安装第一个,具体原因下面说 )

npm install postcss-px2rem --save-dev

表示将px转换为rem   因为我用的这个pc端适配的方法核心原理是rem转换

npm i lib-flexible --save-dev     

这个是阿里用来做设备适配的一个插件,但是当设备宽度较大时,他就会恒定根标签的font-size为54px,所以我们可以一会对这个js文件进行修改,或者是直接自己在其他目录下新建一个,引用自己新建的就好。

安装之后的第一件事就是找到我们的flexible.js 文件,进行修改,这里我可以我直接发源码就好了,这个也是参考了网上的一些代码,(我自己一开始肯定写不出来的,后来看了很久才看明白也是,就是借鉴使用)

我们可以在这个位置找到flexble.js   在node_module中找到这个文件

 进入之后进行修改 修改为一下代码

;(function(win, lib) {
    var doc = win.document;
    var docEl = doc.documentElement;
    var metaEl = doc.querySelector('meta[name="viewport"]');
    var flexibleEl = doc.querySelector('meta[name="flexible"]');
    var dpr = 0;
    var scale = 0;
    var tid;
    var flexible = lib.flexible || (lib.flexible = {});

    if (metaEl) {
        console.warn('将根据已有的meta标签来设置缩放比例');
        var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);
        if (match) {
            scale = parseFloat(match[1]);
            dpr = parseInt(1 / scale);
        }
    } else if (flexibleEl) {
        var content = flexibleEl.getAttribute('content');
        if (content) {
            var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
            var 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) {
        var isAndroid = win.navigator.appVersion.match(/android/gi);
        var isIPhone = win.navigator.appVersion.match(/iphone/gi);
        var devicePixelRatio = win.devicePixelRatio;
        if (isIPhone) {
            // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
            if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
                dpr = 3;
            } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
                dpr = 2;
            } else {
                dpr = 1;
            }
        } else {
            // 其他设备下,仍旧使用1倍的方案
            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 {
            var wrap = doc.createElement('div');
            wrap.appendChild(metaEl);
            doc.write(wrap.innerHTML);
        }
    }

    function refreshRem(){
        var width = docEl.getBoundingClientRect().width;
        if (width / dpr > 540) {
            // width = 540 * dpr;
            //变更
            width = width * dpr;
        }
        var 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(e) {
            doc.body.style.fontSize = 12 * dpr + 'px';
        }, false);
    }


    refreshRem();

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

})(window, window['lib'] || (window['lib'] = {}));

其实核心部分就是修改了这里

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

之前的js 中,不适用与pc设备,只使用与移动设备,对于pc端来讲,html的font-size会被固定为54px,而1rem是等于这个大小的,所以对于pc端来讲就会失去意义,我们设置之后就是,该数值会恒定为设备宽度的1/10,这个就是使用rem的老前辈们的习惯,将这些完成以后,我们可以在main.js中引入我们写好的js,如果是修改原文件,就直接

import 'lib-flexible'

如果是你是自己新建的,就引入自己的。

然后我们可以开始一个小实验测试一下。(使用rem)

这里我随便创建一个盒子(id:test) 然后加上样式

#test{
  width: 5rem;
  height: 5rem;
  background-color: red;
}

我们看一下效果

因为我们的宽度为5rem(1rem=1/10总宽度) 所以对应的盒子宽度为设备一半,那我们修改设备宽度看一下结果

可以看到盒子可以自适应的改变自己的宽度(还是总设备的一半),原理就是每次设备宽度修改,flexblie.js会帮助我们修改根标签的font-size 导致1rem总是等于视口宽度1/10

但是现在的问题是 我们不能总是写rem,因为拿到的设计图一般是px的,自己计算的话

T rem=(N px/ M  ) (1rem=Mpx)  这显然很麻烦 所以就用上了我们第一个插件 , 这个插件的作用就是将px转换为rem 这个是webpack打包时loader会发挥的作用,这个就不细谈了。

用法比较简单,首先打开自己的vue.config.js,在最外面的目录(与package.json同级),如果没有的话就自己创建一个。

打开之后加入如下代码

const px2rem = require('postcss-px2rem')
const postcss = px2rem({
    remUnit: 192 // 基准值
})
module.exports = {
    css: {
        loaderOptions: {
            postcss: {
                plugins: [
                    postcss
                ]
            }
        }
    },
    devServer: {
        port: 3000
    },
}

最后那个devServer是我自己改的端口可以无视掉,需要注意的就是前面的remUnit=192 ,表示1rem=192px 因为我们普遍的设计图为1920*1080  所以1/10宽度为192

全都完成之后我们可以看效果,还是刚刚的盒子,现在我修改css

#test{
  width: 400px;
  height: 400px;
  background-color: red;
}

然后看效果

修改设备宽度

可以看到盒子意见完成了自适应。以上是关于vue+webpack 使用rem适配的方法。

2. vue+vite  

这个和上面的操作基本都是一样的,区别只有 vite 配置时不要再vue.config.js中使用第一个插件,这是webpack的使用方法,vite我们需要再同一层级下创建postcss.config.js

然后加入一下代码

const px2rem = require('postcss-px2rem')
const postcss = px2rem({
    remUnit: 190 // 基准值
})
module.exports = {
    plugins: {
        postcss
    }
}

就可以同样的完成pc端的适配,效果与1中相同。

一些注意事项:

1.  内联样式中的px是无法被适配为rem的

例如

<div style="width:400px;"></div>

2. 直接按上述方法使用可能会对第三方ui 例如element-ui的显示造成影响 

这里提供再postcss中的另一种写法

module.exports = {
  "plugins": {
    "postcss-pxtorem": {
      rootValue: 192,
      propList: ['*'],
      selectorBlackList: [
        'ant'
      ]
    }
  }
}

这样写的话就可以避免对ui库的影响  如果用的是webpack  直接在px2rem-loader属性里加上除去node_modules即可

exclude:/node_modules/

 

(纯萌新笔记)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue + Webpack多页/单页脚手架是一种用于构建Vue.js项目的工具。Vue.js是一个用于构建用户界面的JavaScript框架,而Webpack是一个模块打包工具。 多页/单页脚手架可以根据项目的需求选择构建方式。多页应用指的是每个页面都有自己的HTML文件,而单页应用则是只有一个HTML文件。在多页脚手架中,每个页面都有自己的入口文件和模板文件,Webpack会根据入口文件将各个页面的代码打包成独立的文件。这种方式用于需要多个独立页面的项目。 而在单页脚手架中,只有一个HTML文件和一个入口文件。所有的页面内容都是通过Vue的路由机制来进行渲染和切换。这种方式用于更复杂的单页应用,其中页面之间的切换是通过异步加载和前路由来实现。 使用Vue + Webpack多页/单页脚手架的优点包括: 1. 灵活性:可以根据项目需求选择多页或单页应用方式。 2. 开发效率:脚手架提供了一套默认的置,可以使开发者更快速地开始项目开发。 3. 模块化:使用Webpack打包模块,使得代码更易于管理和维护。 4. 热更新:脚手架支持热更新,可以在开发过程中实时看到修改的效果。 5. 生态系统:Vue.js和Webpack都有庞大的社区支持,可以方便地找到资料和解决问题。 总结起来,Vue + Webpack多页/单页脚手架是一种方便的工具,可以根据项目需求选择合的构建方式,并提供了一系列的开发工具和优化置,使开发更高效、更方便。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值