vue 2.x 大屏自适应组件(摘录 https://gitee.com/zhangfucheng197/large-screen/tree/master/)

javascript 复制代码
<template>
  <div class="screen-wrapper" ref="screenWrapper" :style="wrapperStyle">
    <slot></slot>
  </div>
</template>
<script>
function debounce(fn, delay) {
  let timer = null
  return function (...args) {
    timer = setTimeout(
      () => {
        typeof fn === 'function' && fn.apply(null, args)
        clearTimeout(timer)
      },
      delay > 0 ? delay : 100
    )
  }
}

export default {
  name: 'VScaleScreen',
  props: {
    width: {
      type: [String, Number],
      default: 1920
    },
    height: {
      type: [String, Number],
      default: 1080
    },
    fullScreen: {
      type: Boolean,
      default: false
    },
    autoScale: {
      type: [Object, Boolean],
      default: true
    },
    selfAdaption: {
      type: Boolean,
      default: true
    },
    delay: {
      type: Number,
      default: 500
    },
    boxStyle: {
      type: Object,
      default: () => ({})
    },
    wrapperStyle: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      currentWidth: 0,
      currentHeight: 0,
      originalWidth: 0,
      originalHeight: 0,
      onResize: null,
      observer: null
    }
  },
  watch: {
    selfAdaption(val) {
      if (val) {
        this.resize()
        this.addListener()
      } else {
        this.clearListener()
        this.clearStyle()
      }
    }
  },
  computed: {
    screenWrapper() {
      return this.$refs['screenWrapper']
    }
  },
  methods: {
    initSize() {
      return new Promise((resolve, reject) => {
        this.screenWrapper.parentNode.style.overflow = 'hidden'
        this.screenWrapper.parentNode.scrollLeft = 0
        this.screenWrapper.parentNode.scrollTop = 0

        this.$nextTick(() => {
          if (this.width && this.height) {
            this.currentWidth = this.width
            this.currentHeight = this.height
          } else {
            this.currentWidth = this.screenWrapper.clientWidth
            this.currentHeight = this.screenWrapper.clientHeight
          }
          if (!this.originalHeight || !this.originalWidth) {
            this.originalWidth = window.screen.width
            this.originalHeight = window.screen.height
          }
          resolve()
        })
      })
    },
    updateSize() {
      if (this.currentWidth && this.currentHeight) {
        this.screenWrapper.style.width = `${this.currentWidth}px`
        this.screenWrapper.style.height = `${this.currentHeight}px`
      } else {
        this.screenWrapper.style.width = `${this.originalWidth}px`
        this.screenWrapper.style.height = `${this.originalHeight}px`
      }
    },
    handleAutoScale(scale) {
      if (!this.autoScale) return
      const screenWrapper = this.screenWrapper
      const domWidth = screenWrapper.clientWidth
      const domHeight = screenWrapper.clientHeight
      const currentWidth = document.body.clientWidth
      const currentHeight = document.body.clientHeight
      screenWrapper.style.transform = `scale(${scale},${scale}) `
      let mx = Math.max((currentWidth - domWidth * scale) / 2, 0)
      let my = Math.max((currentHeight - domHeight * scale) / 2, 0)
      if (typeof this.autoScale === 'object') {
        !this.autoScale.x && (mx = 0)
        !this.autoScale.y && (my = 0)
      }
      this.screenWrapper.style.margin = `${my}px ${mx}px`
    },
    updateScale() {
      const screenWrapper = this.screenWrapper
      const currentWidth = document.body.clientWidth
      const currentHeight = document.body.clientHeight
      const realWidth = this.currentWidth || this.originalWidth
      const realHeight = this.currentHeight || this.originalHeight
      const widthScale = currentWidth / realWidth
      const heightScale = currentHeight / realHeight
      if (this.fullScreen) {
        screenWrapper.style.transform = `scale(${widthScale},${heightScale})`
        return false
      }
      const scale = Math.min(widthScale, heightScale)
      this.handleAutoScale(scale)
    },
    initMutationObserver() {
      const screenWrapper = this.screenWrapper
      const observer = (this.observer = new MutationObserver(() => {
        this.onResize()
      }))

      observer.observe(screenWrapper, {
        attributes: true,
        attributeFilter: ['style'],
        attributeOldValue: true
      })
    },
    clearListener() {
      window.removeEventListener('resize', this.onResize)
    },
    addListener() {
      window.addEventListener('resize', this.onResize)
    },
    clearStyle() {
      const screenWrapper = this.screenWrapper
      screenWrapper.parentNode.style.overflow = 'auto'

      screenWrapper.style = ''
    },
    async resize() {
      if (!this.selfAdaption) {
        return
      }
      await this.initSize()
      this.updateSize()
      this.updateScale()
    }
  },
  mounted() {
    this.onResize = debounce(() => {
      this.resize()
    }, this.delay)
    this.$nextTick(() => {
      if (this.selfAdaption) {
        this.resize()
        this.addListener()
      }
    })
  },
  beforeDestroy() {
    this.clearListener()
  }
}
</script>

<style scoped>
.screen-box {
  overflow: hidden;
  background-size: 100% 100%;
  background: #000;
  width: 100vw;
  height: 100vh;
}

.screen-wrapper {
  transition-property: all;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 500ms;
  position: relative;
  overflow: hidden;
  z-index: 100;
  transform-origin: left top;
}
</style>
javascript 复制代码
<template>
  <VScaleScreen :width="1920" :height="969">
    <div class="container">
      <Header />
      <Content />
      <Footer />
    </div>
  </VScaleScreen>
</template>

<script>
import Header from './layout/Header.vue'
import Footer from './layout/Footer.vue'
import Content from './layout/Content.vue'
import VScaleScreen from './layout/VScaleScreen.vue'

export default {
  components: {
    Header,
    Content,
    Footer,
    VScaleScreen
  },
  data() {
    return {}
  },
  mounted() {
    document.body.style.backgroundColor = '#141414'
  }
}
</script>

<style scoped>
.container {
  background-color: #141414;
  color: #fff;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
</style>

摘录自 大屏组件

找了很久,发现这个可以完美解决我的我问题

在此做记录

相关推荐
Dream-Y.ocean1 小时前
鸿蒙PC平台宅匠 3D 室内设计适配实战:基于 Electron 壳方案的 Three.js 双渲染引擎与参数化户型编辑器开发
javascript·3d·harmonyos
Highcharts.js2 小时前
Highcharts Gantt使用符号的自定义数据标签开发甘特图示例
javascript·甘特图·highcharts·图表开发·实战代码·响应式图表
FRing033 小时前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2
Java小卷4 小时前
JuanForm vs FormCreate!Vue3 表单引擎联动配置 PK!
vue.js·低代码
kyriewen5 小时前
Skills 榜前 10 我全装了:只有 3 个能直接用
前端·javascript·程序员
工控丫丫6 小时前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库
Dream-Y.ocean9 小时前
鸿蒙PC平台星图遥感适配实战:基于 Electron 壳方案的纯 JavaScript 遥感图像处理引擎开发
javascript·electron·harmonyos
螺丝钉tina9 小时前
[Playwright ][16]Playwright + TypeScript API 自动化测试实战:API测试
前端·javascript·typescript
Highcharts.js11 小时前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
Java后端的Ai之路12 小时前
【AIAgent开发】-Agent工具封装成CLI(纯干货!!!)
java·javascript·人工智能·agent·cli