# 页面多分辨率适配

# 适配方案

前端多分辨率适配的方案有多种,主要包括以下内容:

  • 使用rem响应式布局,代码需要重构
  • 使用scale属性,维护已有页面较为容易,页面相对尺寸不变;缺点是页面缩放时字体会出现一定的模糊。
  • 使用MutationObserver监听Dom

# 直接使用scale属性

通过计算当前页面或者当前设备物理分辨率,与设计图分辨率的差别,分别计算x、y方向的缩放因子。通过监听浏览器onresize事件,动态调整显示页面的缩放比例,以实现自适应的效果。

  mounted () {
    // 处理屏幕宽高比
    this.handleScreenAuto()
    window.onresize = () => {
      this.handleScreenAuto()
    }
  },
  beforeDestroy () {
    window.onresize = null
  },
  methods: {
    // 多分辨率显示器适配
    handleScreenAuto () {
      const designDraftWidth = 1920;//设计稿的宽度
      const designDraftHeight = 1080;//设计稿的高度
      const currentWidth = document.documentElement.clientWidth // 当前浏览器宽度
      const currentHeight = document.documentElement.clientHeight // 当前浏览器高度
      
      //宽高相同缩放比例,选择较小的
      // const scale = currentWidth / currentHeight < designDraftWidth / designDraftHeight ?
      //     (currentWidth / designDraftWidth) :
      //     (currentHeight / designDraftHeight);
      // //缩放比例
      // (document.querySelector('#overview_contianer')).style.transform = `scale(${scale}) translate(-50%)`;
      
      // 宽高不同缩放比例
      const widthScale =  currentWidth / designDraftWidth;
      const heightScale = currentHeight / designDraftHeight;
      // console.log(widthScale,heightScale)
      (document.querySelector('#overview_contianer')).style.transform = `scale(${widthScale},${heightScale})`;
    }
  }

# 使用MutationObserver监听

<template>
  <div :id="name" :ref="refName">
    <slot v-if="ready"></slot>
  </div>
</template>
<script>
export default {
  name: 'BaseContainer',
  props: {
    // 区分组件
    name: String,
    options: Object,
    refName: String,
  },
  data() {
    return {
      width: 0, // 设计图宽度
      height: 0, // 设计图高度
      originalWidth: 0, // 设备屏幕物理宽度
      originalHeight: 0, // 设备屏幕物理高度
      ready: false,
      context: null,
      dom: null,
      observer: null,
    };
  },
  mounted() {
    this.ready = false;
    this.context = this.$refs[this.refName];
    this.initSize().then(() => {
      this.updateSize();
      this.updateScale();
      window.addEventListener('resize', this.onResize);
      this.initMutationObserver();
      this.ready = true;
    });
  },
  methods: {
    // 初始化尺寸
    async initSize() {
      await this.$nextTick();
      this.dom = this.$refs[this.refName];
      if (this.options && this.options.width && this.options.height) {
        this.width = this.options.width;
        this.height = this.options.height;
      } else {
        this.width = this.dom.clientWidth;
        this.height = this.dom.clientHeight;
      }
      if (!this.originalWidth || !this.originalHeight) {
        this.originalWidth = window.screen.width;
        this.originalHeight = window.screen.height;
      }
    },
    // 更新尺寸
    updateSize() {
      if (this.width && this.height) {
        this.dom.style.width = `${this.width}px`;
        this.dom.style.height = `${this.height}px`;
      } else {
        this.dom.style.width = `${this.originalWidth}px`;
        this.dom.style.height = `${this.originalHeight}px`;
      }
    },
    // 更新宽高比
    updateScale() {
      const currentWidth = document.body.clientWidth;
      const currentHeight = document.body.clientHeight;

      const realWidth = this.width || this.originalWidth; // 默认用设计尺寸
      const realHeight = this.height || this.originalHeight; 
      const widthScale = currentWidth / realWidth;
      const heightScale = currentHeight / realHeight;
      this.dom.style.transform = `scale(${widthScale},${heightScale})`;
    },
    // onresize 事件响应函数
    onResize() {
      this.initSize().then(() => {
        this.updateScale();
      });
    },
    // 初始化事件监听器
    initMutationObserver() {
      // 创建MutationObserver 在DOM发生变化时被调用
      const MutationObserver = window.MutationObserver;
      this.observer = new MutationObserver(this.onResize);
      this.observer.observe(this.dom, {
        attributes: true, // 监听所有节点属性值
        attributeFilter: ['style'], // 指定被监听的属性列表
        attributeOldValue: true, // 记录上一次被监听的节点属性变化
      });
    },
    removeMutationObserver() {
      if (this.observer) {
        this.observer.disconnect(); // 阻止继续接收变化的通知
        this.observer.takeRecords();
        this.observer = null;
      }
    },
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.onResize);
    this.removeMutationObserver();
  },
};
</script>
<style scoped>
#base-container {
  position: fixed;
  top: 0;
  left: 0;
  overflow: hidden;
  transform-origin: left top;
  z-index: 999;
}
</style>

Last Updated: 12/23/2024, 4:18:13 AM