大小屏适配

简介: 优化

方案一:lib-flexible

移动端适配:

一般而言,lib-flexible 并不独立出现,而是搭配 px2rem-loader 一起做适配方案,目的是 自动将 CSS 中的 px 转换成 rem。以下为它在 vue 中的使用

1、安装

npm install lib-flexible --save-dev

2、在 main.js 中引入 lib-flexible

// px2rem 自适应
import 'lib-flexible'

3、安装 px2rem-loader

npm install px2rem-loader --save-dev

4、配置 px2rem-loade

vue-cli 2.x版本

4.1、在 build/utils.js 中,找到 exports.cssLoaders,作出如下修改:

const px2remLoader = {
    loader: 'px2rem-loader',
    options: {
        remUint: 75 // 以设计稿 750 为例, 750 / 10 = 75
    }
}

4.2、找到 generateLoaders 中的 loaders 配置,作出如下:

// 注 释 掉 这 一 行 
// const loaders = options.usePostCSS ? [cssLoader,postcssLoader] : [cssLoader]
// 修改为 
const loaders = [cssLoader, px2remLoader]
if (options.usePostCSS) {
    loaders.push(postcssLoader)
}

vue-cli 3.x版本

在项目根目录新建文件 vue.config.js,然后如下配置:

module.exports = { 
    css: {
        loaderOptions: { css: {},
        postcss: {
                plugins: [ 
                    require('postcss-px2rem')({
                        // 以设计稿 750 为例, 750 / 10 = 75
                        remUnit: 75
                    }),
                ]
            }
        }
    },
};

重新 npm run dev,完

大屏适配

​ 假如我们屏幕尺寸要做以 3840 x 2160 为设计稿的适配,那么我们的 remUnit 的值则 改为 384。此时就需要修改源码啦!

1、找到源码

打开./node_modules/lib-flexible/flexible.js,找到如下片段源码:

function refreshRem(){ 
    var width = docEl.getBoundingClientRect().width;
    if (width / dpr > 540) { 
        width = 540 * dpr;
    }
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    flexible.rem = win.rem = rem;
}
解决:当屏幕宽度除以 dpr(dpr 是一个倍数,此处一般为 1) 大于 540 这个特定值的时候,那么就不再进行适配了问题

2、修改源码

假如我要适配的大屏幕尺寸是基于 3840 的设计稿, 而要求最小范围是 1980,最大为 5760,那么我们要修改的则变为

function refreshRem(){ 
    var width = docEl.getBoundingClientRect().width;
    if (width / dpr < 1980) { 
        width = 1980 * dpr;
    } else if (width / dpr > 5760) { 
        width = 5760 * dpr;
    }
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    flexible.rem = win.rem = rem;
}
注:修改完成后,重启项目,则会适配到相应的尺寸。此外还有一个提示,当脱离掉 node_modules 重新 npm install 项目依赖时还是需要重新修改一遍的!

方案二:监听浏览器的窗口大小

1、初始化的时候获得大屏幕的比例

2、把这个比例设置给CSS的scale变量

3、监听浏览器的窗口大小,将新的比例赋给scale变量

<div class="ScaleBox" ref="ScaleBox" >
    
mounted() {
    this.setScale(); 
    window.addEventListener("resize", this.setScale);
},
methods: {
    getScale() { 
        const { width, height } = this;
        let ww = window.innerWidth / width;
        let wh = window.innerHeight / height;
        return ww < wh ? ww : wh;
    },
    setScale() {
        this.scale = this.getScale();
        this.$refs.ScaleBox.style.setProperty("--scale", this.scale);
    },
}

#ScaleBox { 
  --scale: 1;
}
.ScaleBox {
    transform: scale(var(--scale)) ;
}

VUE 组件就封装

<template>
    <div class="wrap">
        <div class="ScaleBox" ref="ScaleBox" :style="{width, height}">
            <BigScreen></BigScreen>
        </div>
    </div>
</template>
<script>
export default { 
    name: "ScaleBox",
    props: { 
       width: {
           type: Number,
           default: 1920
       },
       height: {
           type: Number,
           default: 1080
       }
    },
    data() {
        return {
            scale: null
        };
    },
    mounted() {
        this.setScale();                                     window.addEventListener("resize", this.setScale);
    }, 
    methods: {
        // 获取较小比例的一条边, 这样较大比例的一条边就可以按照既定的比例缩放了, width 和 height 是设置的默认比例,window.innerWidth 和window.innerHeight 是大屏幕的缩放尺寸.
        getScale() { 
            const { width, height } = this;
            let ww = window.innerWidth / width;
            let wh = window.innerHeight / height;
            return ww < wh ? ww : wh;
        },
        setScale() {
            this.scale = this.getScale();
            this.$refs.ScaleBox.style.setProperty("--scale", this.scale);
        },
        debounce(fn, delay) {
            let delays = delay || 500;
            let timer;
            return function() {
                let th = this;
                let args = arguments;
                if (timer) { clearTimeout(timer);
            }
            timer = setTimeout(function() {
                timer = null;
                fn.apply(th, args);
            }, delays);
        };
    }
 }
};
</script>
<style >
#ScaleBox { 
    --scale: 1;
}
.wrap {
    background: #eee; width: 100%;
    height: 5000px;
}
.ScaleBox {
    transform: scale(var(--scale)) translate(-50%, -50%);
    display: flex;
    height: 100%;
    flex-direction: column;
    transform-origin: 0 0;
    position: absolute;
    left: 50%;
    top: 50%;
    transition: 0.3s;
    z-index: 999;
}
</style>
目录
相关文章
|
SQL 关系型数据库 MySQL
探索Gorm - Golang流行的数据库ORM框架
探索Gorm - Golang流行的数据库ORM框架
|
XML Java Maven
IDEA安装及创建Maven项目教程【史上最详细】(二)
IDEA安装及创建Maven项目教程【史上最详细】(二)
1498 0
|
前端开发
饿了么el-dialog自定义内容以及el-dialog自定义样式
饿了么el-dialog自定义内容以及el-dialog自定义样式
947 0
|
12月前
|
JavaScript 前端开发
JS try catch用法:异常处理
【10月更文挑战第12天】try/catch` 是 JavaScript 中非常重要的一个特性,它可以帮助我们更好地处理程序中的异常情况,提高程序的可靠性和稳定性。
508 56
2024年 | 12月云大使推广奖励规则
【近期云大使规则升级】①上线企业云大使提现功能。②增加返利订单类目。③优化推广奖励限制。④提升首购后订单返利比例。⑤新增沉睡用户返利 。⑥推荐企业认证新用户首购最高奖励45%。
|
网络协议 Ubuntu 前端开发
如何在操作使用ufw设置防火墙
如何在操作使用ufw设置防火墙
|
Java 数据库 Maven
谷粒商城笔记+踩坑(1)——架构、项目环境搭建、代码生成器
项目介绍、项目环境搭建、docker配置mysql,redis,jdk,maven、人人开源、快速开发、安装nodejs、逆向工程搭建,人人开源代码生成器
谷粒商城笔记+踩坑(1)——架构、项目环境搭建、代码生成器
|
缓存 监控 负载均衡
Gateway
【7月更文挑战第3天】
308 12
|
存储 索引
逻辑地址与物理地址的转换
最近一直在学8086,上课老师突然问了个这。对于问题“8086 CPU 能提供20位的地址信息,可直接对1M个存储单元进行访问,而CPU内部可用来提供地址信息的寄存器都是16位,那怎样用16位寄存器来实现20位地址寻址呢"明白了不少。
356 0
|
缓存 监控 中间件
【Flume中间件】(1)监听netcat44444端口并将数据打印到控制台
【Flume中间件】(1)监听netcat44444端口并将数据打印到控制台
575 84
【Flume中间件】(1)监听netcat44444端口并将数据打印到控制台