vue3自定义Hook之useResize

  • useResize 是一个自定义 Vue3 Hook,用于实现大屏项目的自适应布局。它通过监听窗口尺寸变化,自动调整页面元素的缩放比例,确保在不同分辨率下都能保持一致的视觉效果。
import { onBeforeMount, onBeforeUnmount, onMounted, ref } from "vue";

// 默认适配的宽高
export const width = 1920;
export const height = 1080;

type ResizeType = {
    w?: number;
    h?: number;
    fullScreen?: boolean;
    delay?:number;
}

export const useResize = (options: ResizeType = {}) => {
    const { w = width, h = height, fullScreen = false, delay = 100 } = options;

    const screenRef = ref();
    const scale = ref(1);

    function resize() {
        // 获取浏览器的高度
        const clientWidth = document.body.clientWidth;
        const clientHeight = document.body.clientHeight;

        // 计算比例缩放
        const scaleW = clientWidth / w;
        const scaleH = clientHeight / h;
        scale.value = Math.min(scaleW, scaleH); // 保持内容完整且比例不变

        if(fullScreen) {
            screenRef.value.style.transform = `scale(${scaleW}, ${scaleH})`;
        }else {
            screenRef.value.style.transform = `scale(${scale.value})`;
            // 设置居中
            screenRef.value.style.left = `${(clientWidth - w * scale.value) / 2}px`;
            screenRef.value.style.top = `${(clientHeight - h * scale.value) / 2}px`;
        }
    }

    const resizeDelay = debounce(resize, delay);

    onMounted(()=> {
        if(screenRef.value) {
            resize();
            window.addEventListener('resize', resizeDelay);
        }
    });

    onBeforeUnmount(()=> {
        window.removeEventListener('resize', resizeDelay);
    });

    return {
        screenRef,
        scale
    }
}

/**
 * 防抖
 */
function debounce(fn: Function, delay: number) {
    let timer:NodeJS.Timeout;
    return function(...args: any[]) {
        if(timer) clearTimeout(timer);
        timer = setTimeout(()=> {
            typeof fn === 'function' && fn.apply(null, args);
            clearTimeout(timer);
        }, delay > 0 ? delay : 100);
    }
}

使用方式

  <template>
   <div class="screen-container">
      <div ref="screenRef" class="screen-wrap">
          <Header/>
          <div class="screen-main">
            <div class="screen-left">
               <Left/>
            </div>
            <div class="screen-center">
               <Center/>
            </div>
            <div class="screen-right">
                <Right/>
            </div>
          </div>
      </div>
    </div>
  </template>
  <script lang="ts" setup>
    import { useResize } from './useResize';
    const { screenRef } = useResize();
  </script>
posted @ 2025-05-02 21:55  HuangBingQuan  阅读(99)  评论(0)    收藏  举报