大屏适配方案

1,187 阅读2分钟

说是大屏适配方案,不如说是一种前端多尺寸的适配方案。不过大屏类型项目更具有代表意义:始终要保持设计图的布局、始终要在不同尺寸屏幕下保持整体效果的统一。 这种需求,常见的做法有以下几个方案

  1. 使用vw作为单位,可以保证布局的完整还原,没有额外的适配要求,算是等比缩放比较简单粗暴的方案。缺点是单位换算很麻烦,当然也可以像pxtorem这种思路,写一个插件,定义一个标准的vw宽度,都参照这个标准宽度完成开发后使用插件完成单位转换。
  2. 使用rem,同样能够保证布局的完整还原,但是在低分屏(72)中,字号缩小到10号以后就不会继续缩小了,所以有些极端的场景,显示可能不好。同时还得做基础fontsize的实时变化,在window resize的时候来设置一个合理的字体大小。缺点:若只有项目中的部分页面需要等比缩放保持页面布局的时候,修改字体大小可能影响到其他页面。
  3. rem与vw结合,这个综合1、2可以得出。
  4. 使用缩放,这个也是本文的介绍重点。

使用缩放实现页面适配

背景:项目需要开发大屏,但是大屏只是项目中的一小部分功能。要求大屏可以在管理系统中进行全屏展示,非全屏时也能正常展示。并且大屏可能放在不同的分辨率的设备中展示。

css缩放的时候,除了图片,其他内容时矢量的,不会出现失真,所以设计的时候,首先要保证素材有足够的清晰度,这样即使缩放比较大,也不会模糊。

使用特性:css3: transform: scale(x),ResizeObserver监听div的大小变更。 transform: scale是标准内容,兼容性好。

实现思路时做一个容器,监听的大小,计算出缩放比例,来缩放容器内的内容,可以把容器封装为组件,在需要的地方使用即可。

<template>
  <div class="auto-scale" :id="divId">
    <div class="transform-origin-lt" :style="{ transform: `scale(${scale})` }">
      <slot></slot>
    </div>
  </div>
</template>

<script lang="ts">
  import { defineComponent, onMounted, ref, nextTick, PropType } from 'vue';
  import { buildUUID } from '/@/utils/uuid';

  export default defineComponent({
    name: 'AutoScale',
    props: {
      designWidth: {
        type: Number as PropType<number>,
        default: 1920,
      },
    },
    setup(props) {
      const divId = buildUUID();
      let scale = ref(1);
      onMounted(() => {
        // 监听div的大小改变
        const scaleContainer: any = document.getElementById(divId);

        const resizeObserver = new ResizeObserver(() => {
          nextTick(() => {
            scale.value = scaleContainer.offsetWidth / props.designWidth;
          });
        });
        resizeObserver.observe(scaleContainer);
      });
      return {
        divId,
        scale,
      };
    },
  });
</script>

<style scoped lang="less">
  .auto-scale {
    width: 100%;
    height: 100%;

    .transform-origin-lt {
      transform-origin: left top;
    }
  }
</style>

移动端的话,推荐考虑pxtorem,然后约定一个宽度,之后所有的屏幕都参照约定来调整rem的基础大小。要是不限制技术的话,推荐uni-app,比较成熟的框架,各种适配都做得很棒了。