vue大屏放大缩小适配方案之scale,直接用超简单

文章介绍了如何使用Vue2开发组件,分别实现全屏情况下不留白的缩放和等比例放大缩小并保持美观的两种方法,以及在父组件中引用和应用这些组件的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果图:

全屏情况:

vue2组件代码如下:

1. 适应长度宽度,不留白,(本demo是第一种,不留白)

<template>
  <div :style="styleObject" class="scale-box">
    <slot />
  </div>
</template>

<script>
import debounce from 'lodash.debounce'
export default {
  components: {},
  props: {
    width: {
      type: Number,
      default: 1920
    },
    height: {
      type: Number,
      default: 1080
    }
  },
  data() {
    return {
      scale: this.getScale()
    }
  },
  computed: {
    styleObject() {
      const obj = {
        transform: `scaleY(${this.scale.y}) scaleX( ${this.scale.x}) translate(-50%, -50%)`,
        WebkitTransform: `scale(${this.scale}) translate(-50%, -50%)`,
        width: this.width + 'px',
        height: this.height + 'px'
      }
      return obj
    }
  },
  mounted() {
    this.getScale()
    window.addEventListener('resize', this.setScale)
  },
  beforeDestroy() {
    window.addEventListener('resize', this.setScale)
  },
  methods: {
    getScale() {
      // 固定好16:9的宽高比,计算出最合适的缩放比,宽高比可根据需要自行更改
      console.log(window.innerWidth, 'window.innerWidth')
      const ww = window.innerWidth / this.width
      const wh = window.innerHeight / this.height
      // return ww < wh ? ww : wh
      return { x: ww, y: wh }
    },
    setScale: debounce(function() {
      // 获取到缩放比,设置它
      const scale = this.getScale()
      this.scale = scale
    }, 300)
  }
}
</script>

<style scoped lang="scss">
.scale-box {
  transform-origin: 0 0;
  position: fixed;
  left: 50%;
  top: 50%;
  transition: 0.3s;
}
</style>

2. 等比例放大缩小,会留白,但页面不会变形,更为美观,背景色设置与主题色同色,效果更佳

<template>
  <div :style="styleObject" class="scale-box">
    <slot />
  </div>
</template>

<script>
import debounce from 'lodash.debounce'
export default {
  components: {},
  props: {
    width: {
      type: Number,
      default: 1920
    },
    height: {
      type: Number,
      default: 1080
    }
  },
  data() {
    return {
      scale: this.getScale()
    }
  },
  computed: {
    styleObject() {
      const obj = {
        transform: `scale(${this.scale}) translate(-50%, -50%)`,
        WebkitTransform: `scale(${this.scale}) translate(-50%, -50%)`,
        width: this.width + 'px',
        height: this.height + 'px'
      }
      return obj
    }
  },
  mounted() {
    this.getScale()
    window.addEventListener('resize', this.setScale)
  },
  beforeDestroy() {
    window.addEventListener('resize', this.setScale)
  },
  methods: {
    getScale() {
      // 固定好16:9的宽高比,计算出最合适的缩放比,宽高比可根据需要自行更改
      console.log(window.innerWidth, 'window.innerWidth')
      const ww = window.innerWidth / this.width
      const wh = window.innerHeight / this.height
      return ww < wh ? ww : wh
    },
    setScale: debounce(function() {
      // 获取到缩放比,设置它
      const scale = this.getScale()
      this.scale = scale
    }, 500)
  }
}
</script>

  <style scoped lang="scss">
  .scale-box {
    transform-origin: 0 0;
    position: fixed;
    left: 50%;
    top: 50%;
    transition: 0.3s;
  }
  </style>

父组件引用方式:

<template>
  <div id="visual">
    <visualView>
      <div class="visual-app">
        <header>
       头部组件
        </header>
        <section>
          <router-view />
        </section>
      </div>
    </visualView>
  </div>
</template>

<script>
import visualView from '@/components/visualView'

export default {
  components: { visualView},
  data() {
    return {}
  },
  computed: {},
  created() {},
  methods: {}
}
</script>

<style lang="scss" scoped>
#visual {
  height: 100%;
  width: 100%;
  background: #121d2f;
  .visual-app {
    height: 100%;
    width: 100%;
    header {
      width: 100%;
      height: 95px;
    }
    section {
      width: 100%;
      padding: 25px 16px;
      height: calc(100% - 95px);
      color: aliceblue;
    }
  }
}
</style>

### Vue适配的最佳实践 在Vue项目中进行适配时,通常需要考虑幕分辨率、设备像素比以及动态缩放等因素。以下是几种常见且有效的Vue适配方案及其具体实现方法。 #### 方案一:基于`postcss-px2rem`的适配方式 通过安装并配置 `postcss-px2rem` 插件,可以将样式中的 `px` 单位自动转换为 `rem` 单位,从而实现响应式布局。此插件的核心在于动态计算根节点字体小 (`html font-size`) 并将其作为基础单位[^2]。 ```javascript // vue.config.js 配置示例 module.exports = { css: { loaderOptions: { postcss: { plugins: [ require('postcss-px2rem')({ remUnit: 192, // 设计稿宽度除以10得到的基础值 remPrecision: 8, }), ], }, }, }, }; ``` 为了支持不同幕尺寸下的动态调整,在 `main.js` 中引入自定义的 `flexible.js` 文件来实时更新根节点字体小: ```javascript function refreshRem() { const docEl = document.documentElement; const dpr = window.devicePixelRatio || 1; let width = docEl.getBoundingClientRect().width; if (width / dpr < 1920) { width = 1920 * dpr; } else if (width / dpr > 5760) { width = 5760 * dpr; } const rem = (width / 24); // 基于设计稿宽度设定的比例因子 docEl.style.fontSize = `${rem}px`; } window.addEventListener('resize', refreshRem); refreshRem(); ``` 这种方法适用于多数场景,但在某些特殊情况下可能不够灵活[^3]。 --- #### 方案二:使用`ScaleBox`组件封装统一比例缩放逻辑 对于更复杂的业务需求或者希望减少手动干预的情况,可以通过创建一个名为 `<scale-box>` 的全局容器组件来完成整个页面内容按固定比例放大缩小的功能[^4]。 该组件的主要作用是在父级元素上应用 CSS 变换来模拟整体拉伸效果,而子组件则无需关心具体的物理尺寸变化,只需按照标准的设计稿规格(如1920×1080)正常书写CSS即可。 ```vue <template> <div :style="{ transform: `scale(${scale})`, transformOrigin: 'left top' }"> <slot></slot> </div> </template> <script> export default { data() { return { scale: 1, }; }, mounted() { this.updateScale(); window.addEventListener('resize', this.updateScale); }, beforeDestroy() { window.removeEventListener('resize', this.updateScale); }, methods: { updateScale() { const containerWidth = Math.min(window.innerWidth, 1920); this.scale = containerWidth / 1920; }, }, }; </script> ``` 这种方式特别适合那些只需要简单平铺多个模块而不涉及复杂交互操作的数据可视化类应用界面开发工作流程之中。 --- #### 综合比较与推荐 两种主流技术路线各有优劣之处: - **PostCSS Px-to-Rem 转换法** 更加贴近传统移动端网页制作习惯,易于维护和扩展;但对于极端高型显示终端的支持度稍显不足。 - **Scale Box 缩放机制** 则完全规避掉了单个DOM对象属性重新解析渲染过程所带来的性能开销问题,同时还能很好地兼容各类异形拼接墙环境下的无缝衔接表现形式。 因此,在实际工程项目选型阶段应当充分权衡两者之间的差异特性后再做决定。 ---
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值