Vue 自适应大屏组件

523 阅读1分钟

效果

屏幕录制2023-07-04-10.04.25.min.gif

代码实现

// index.jsx
import { defineComponent, onBeforeUnmount, onMounted, ref } from 'vue'
import { useDebounceFn } from '@vueuse/core'
import './index.less'

export default defineComponent({
  props: {
    designWidth: {
      type: Number,
      default: 1920
    },
    designHeight: {
      type: Number,
      default: 1080
    }
  },
  setup(props, { slots }) {
    const scale = ref(1)
    const { designHeight, designWidth } = props

    const calcScale = () => {
      const screenWidth = document.documentElement.clientWidth
      const screenHeight = document.documentElement.clientHeight

      let _scale =
        screenWidth / screenHeight < designWidth / designHeight
          ? screenWidth / designWidth
          : screenHeight / designHeight

      scale.value = _scale
    }

    const debounceCalcScale = useDebounceFn(calcScale, 300)

    onMounted(() => {
      calcScale()
      window.addEventListener('resize', debounceCalcScale)
    })
    onBeforeUnmount(() => {
      window.removeEventListener('resize', debounceCalcScale)
    })

    return () => (
      <div class="scale-view-wrapper">
        <div
          class="scale-view-screen"
          style={{
            width: `${designWidth}px`,
            height: `${designHeight}px`,
            transform: `scale(${scale.value}) translate(-50%)`
          }}
        >
          {slots.default?.()}
        </div>
      </div>
    )
  }
})
// index.less
.scale-view-wrapper {
  height: 100vh;
  width: 100vw;
  position: relative;
  overflow: hidden;
  background-size: 100% 100%;
  background-position: center;
  background-repeat: no-repeat;
}
.scale-view-screen {
  transform-origin: 0 0;
  position: absolute;
  left: 50%;
}

使用

import ScaleScreen from '@/components/ScaleScreen'
import styles from './index.module.less'
export default {
  setup() {
    return () => (
      // 这里传入设计稿宽高
      <ScaleScreen designHeight={1080} designWidth={1920}>
        <div class={styles['wrapper']}>
          <img
            class={styles['bg']}
            src={new URL('./static/lezhen-step1.png', import.meta.url).href}
          />
        </div>
      </ScaleScreen>
    )
  }
}