前言

最近公司有个大屏的需求,第一次做,踩了不少坑,同时也还有些疑问。
希望能给需要的朋友避坑,也欢迎大佬指点!

明确需求再决定适配方案

大屏最最重要的就是适配问题,所以第一步我们需要先明确需求,根据不同需求再考虑最优的适配方案。
一般有以下几种:

16:9(1920*1080)
16:9(3840*2160)
16:10(1920*1200)
21:9(3440*1440)

一般设计稿是给1920*1080,也就是16:9
第一种情况:如果只需要适配同比例,eg. 16:9,最简单的适配方案就是scale。主要代码如下:

ScreenAdapter.vue

<template>
    <div class="screen-adapter" id="screen-adapter">
        <div class="content-wrap" :style="style">
            <slot />
        </div>
    </div>
</template>
<script>
export default {
    name: 'screenAdapter',
    //参数注入
    props: {
        width: { // 设计图尺寸宽
            type: Number,
            default: 1920
        },
        height: {
            type: Number,
            default: 1080
        }
    },
    data() {
        return {
            style: {
                width: `${this.width}px`,
                height: `${this.height}px`,
                transform: 'scale(1)', // 默认不缩放,垂直水平居中
            }
        }
    },
    mounted() {
        this.setScale();
        this.onresize = this.debounce(() => this.setScale(), 100);
        window.addEventListener('resize', this.onresize);
    },
    methods: {
        debounce: (fn, t) => {
            const delay = t || 500
            let timer
            return function () {
                const args = arguments
                if (timer) {
                    clearTimeout(timer)
                }
                const context = this
                timer = setTimeout(() => {
                    timer = null
                    fn.apply(context, args)
                }, delay)
            }
        },
        // 获取放大缩小比例
        getScale() {
            const w = window.innerWidth / this.width;
            const h = window.innerHeight / this.height;
            return w < h ? w : h;
        },
        // 设置比例
        setScale() {
            this.style.transform = `scale(${this.getScale()})`;
        }
    },
    destroyed() {
        window.removeEventListener('resize', this.onresize)
    }
}
</script>
<style lang="less" scoped>
.screen-adapter {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    transition: all 0.3s;
    position: relative;
    background: url('../../../assets/img/screen-bg.jpg') 100% 100%;
    .content-wrap {
        transform-origin: 0 0;
    }
}
</style>

在大屏页面,把screen-adapter包在在外层使用即可。是不是很简单?(一定注意是同比例的哦,如果需要适配不同比例,请继续往下看)
第二种情况:适配不同比例。我采用的是vw,vh,rem及媒体查询。主要代码如下:

src/assets/styles/utils.less

// 默认设计稿的宽度
@designWidth: 1920;
// 默认设计稿的高度
@designHeight: 1080;

// px转vw的函数
.pxToVW (@px, @attr: width) {
    @vw: (@px / @designWidth) * 100;
    @{attr}: ~"@{vw}vw";
}
// px转vh的函数
.pxToVH (@px, @attr: height) {
    @vh: (@px / @designHeight) * 100;
    @{attr}: ~"@{vh}vh";
}
vue.config.js

css: {
        loaderOptions: {
            less: {
                .......
                // 全局配置utils.less,详细配置参考vue-cli官网
                prependData: '@import "@/assets/styles/utils.less";'
            }
        }
    },

做好以上配置后,重启项目,就可以使用了,示例如下:

.pxToVH(156, height); // 156是设计稿的px值,第二个参数是属性;VH默认属性是’height’;这样就把156px转成了以vh为单位的值。

.pxToVW(156, width); // 同上
另外需要注意的是,字体的设置是根据页面根元素的大小改变而改变的,所以字体设置rem的同时需要设置媒体查询。

到这里基本上通过这次大屏项目总结的经验基本就说完了。但是也有些疑问,比如:
border-radius: 8px; 这个px怎么转?转成什么值更合适呢?
欢迎大佬来指正!!!

Logo

智屏生态联盟致力于大屏生态发展,利用大屏快应用技术降低开发者开发、发布大屏应用门槛

更多推荐