vue大屏适配方案

1.锁死分辨率的方式

class DevicePixelRatio {
    constructor() {
      // this.flag = false;
    }
    // 获取系统类型
    _getSystem() {
      let flag = false;
      var agent = navigator.userAgent.toLowerCase();
      //		var isMac = /macintosh|mac os x/i.test(navigator.userAgent);
      //		if(isMac) {
      //			return false;
      //		}
      // 现只针对windows处理,其它系统暂无该情况,如有,继续在此添加
      if (agent.indexOf('windows') >= 0) {
        return true;
      }
    }
    // 获取页面缩放比例
    //	_getDevicePixelRatio() {
    //		let t = this;
    //	}
    // 监听方法兼容写法
    _addHandler(element, type, handler) {
      if (element.addEventListener) {
        element.addEventListener(type, handler, false);
      } else if (element.attachEvent) {
        element.attachEvent('on' + type, handler);
      } else {
        element['on' + type] = handler;
      }
    }
    // 校正浏览器缩放比例
    _correct() {
      let t = this;
      // 页面devicePixelRatio(设备像素比例)变化后,计算页面body标签zoom修改其大小,来抵消devicePixelRatio带来的变化。
      document.getElementsByTagName('body')[0].style.zoom = 1 / window.devicePixelRatio;
      //防止canvas变形
      document.styleSheets[document.styleSheets.length - 1].insertRule('canvas {zoom: ' + 1 / (1 / window.devicePixelRatio) + '}');
    document.styleSheets[document.styleSheets.length - 1].insertRule('canvas {transform: scale(' + 1 / window.devicePixelRatio + ')}');
    document.styleSheets[document.styleSheets.length - 1].insertRule('canvas {transform-origin: 0 0}');
    }
    // 监听页面缩放
    _watch() {
      let t = this;
      t._addHandler(window, 'resize', function() { // 注意这个方法是解决全局有两个window.resize
        // 重新校正
        t._correct()
      })
    }
    // 初始化页面比例
    init() {
      let t = this;
      if (t._getSystem()) { // 判断设备,目前只在windows系统下校正浏览器缩放比例
        // 初始化页面校正浏览器缩放比例
        t._correct();
        // 开启监听页面缩放
        t._watch();
      }
    }
  }
  export default DevicePixelRatio;
  
  

使用:

created() {
    new DevicePixelRatio().init()
  },

2.修改缩放比方式

export const scaleMixin = {
  data() {
    return {
      isScree: false,
    }
  },
  methods: {
    getRatio() {
      var ratio = 0,
        screen = window.screen,
        ua = navigator.userAgent.toLowerCase();

      if (window.devicePixelRatio !== undefined) {
        ratio = window.devicePixelRatio;
      }
      else if (~ua.indexOf('msie')) {
        if (screen.deviceXDPI && screen.logicalXDPI) {
          ratio = screen.deviceXDPI / screen.logicalXDPI;
        }
      }
      else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
        ratio = window.outerWidth / window.innerWidth;
      }

      if (ratio) {
        ratio = Math.round(ratio * 100);
      }
      console.log(ratio)
      return ratio;
    },
    // 计算缩放比例
    getScaleRatio() {
      const baseWidth = 1920; // 基准宽度
      const baseHeight = 1080; // 基准高度
      const screenWidth = window.innerWidth; // 屏幕宽度
      const screenHeight = window.innerHeight; // 屏幕高度
      console.log(screenWidth)
      const ratioX = screenWidth / baseWidth;
      const ratioY = screenHeight / baseHeight;
      return Math.min(ratioX, ratioY); // 取最小比例作为缩放比例
    },
    onresize(event) {
      // 利用屏幕分辨率和window对象的内高度来判断兼容IE
      let winFlag = window.innerHeight === window.screen.height;
      // 利用window全屏标识来判断 -- IE无效
      let isFull = window.fullScreen || document.webkitIsFullScreen;

      if (isFull === undefined) {
        this.isScree = winFlag;
      } else {
        this.isScree = winFlag || isFull;
      }

      // true全屏   false不是全屏
      if (winFlag == true) {

        const scaleRatio = this.getScaleRatio();
        if(this.$refs.wrapper){
          this.$refs.wrapper.style.transform = `scale(${scaleRatio})`;

        }

      }
      if (winFlag == false) {
        if(this.$refs.wrapper){
          this.$refs.wrapper.style.transform = 'inherit';
        }
      }
    },
  },
  beforeDestroy() {
    // 取消监听事件
    window.removeEventListener("resize", this.onresize);
  },
  mounted() {
    this.getRatio();
    window.addEventListener("resize", this.onresize);
    this.onresize()

  },
};

使用:

mixins: [scaleMixin],
<think>好的,我在需要帮助用户了解在Vue2中实适配的方法和最佳实践。根据用户提供的引用内容,他们提到了vue2-scale-box库和基于窗口缩放的方案。首先,我应该先整理这些信息,然后补充其他常见的方法,确保覆盖多种适配方案。 首先,用户提到的vue2-scale-box库是一个成的解决方案,可能通过npm安装后直接使用,这应该是一个比较方便的方法。但需要详细说明如何使用,比如引入组件、设置基准尺寸等步骤。同时,引用中提到根据窗口宽度和高度计算缩放比例,并取较小的比例值,这点需要解释清楚,确保用户理解其原理。 接下来,可能需要考虑其他常见的适配方法,比如rem适配、vw/vh单位、CSS3的transform缩放,或者结合媒体查询的响应式布局。这些方法各有优缺点,比如rem需要动态计算根字体小,vw/vh单位相对于视口,而transform缩放则可能影响性能或元素的位置。 然后,需要将这些方法进行比较,指出各自的适用场景和注意事项。例如,vue2-scale-box适合快速实整体缩放,而rem适配可能在需要精细控制时更合适。同时,最佳实践部分要强调设置基准分辨率、保持比例、处理滚动和字体,以及考虑性能优化。 在生成相关问题的时候,需要围绕这些方法展开,比如如何选择方案、如何处理滚动条、性能优化技巧,以及如何结合多种方法等。确保问题能够帮助用户深入理解不同方案的细节和实际应用中的挑战。 还需要检查是否有遗漏的重要点,比如第三方图表库的适配问题,这可能在实际项目中经常遇到,需要特别说明如何处理ECharts等库的适配,比如监听窗口变化并调用resize方法。 最后,确保回答结构清晰,分点说明,每个方法都有步骤和代码示例(如适用),并且语言符合中文习惯,避免技术术语使用不当。同时,引用标记要正确添加到对应的位置,比如引用[1]和引用[2]分别对应安装库和计算比例的部分。</think>在Vue2中实适配的核心思路是通过动态缩放页面内容来适应不同分辨率。以下是具体方法和最佳实践: ### 一、主流适配方案 1. **vue2-scale-box方案**(推荐) ```javascript import Vue2ScaleBox from 'vue2-scale-box' Vue.use(Vue2ScaleBox) // 在入口文件设置基准分辨率 Vue.prototype.$baseWidth = 1920 Vue.prototype.$baseHeight = 1080 // 页面容器使用 <vue2-scale-box :baseWidth="1920" :baseHeight="1080"> <!-- 内容 --> </vue2-scale-box> ``` 原理:通过监听窗口resize事件,根据当前视口与基准分辨率计算缩放比例,取最小值确保内容完整显示[^2] 2. **CSS transform缩放方案** ```css .wrapper { transform-origin: 0 0; transition: 0.3s; } ``` ```javascript // 在mounted和resize时计算 function setScale() { const scaleX = window.innerWidth / 1920 const scaleY = window.innerHeight / 1080 document.querySelector('.wrapper').style.transform = `scale(${Math.min(scaleX, scaleY)})` } ``` 3. **rem动态计算方案** ```javascript // 设置基准rem值 const baseSize = 1920 / 100 // 19.2px // 动态设置html字体 function setRem() { const scale = document.documentElement.clientWidth / 1920 document.documentElement.style.fontSize = baseSize * Math.min(scale) + 'px' } ``` ### 二、最佳实践 1. **基准分辨率设定** - 推荐使用1920×1080作为开发基准分辨率 - 设计稿按1:1比例制作 - 特殊场景可设3840×2160(4K) 2. **关键处理技巧** - 添加resize监听并防抖处理 ```javascript window.addEventListener('resize', _.debounce(setScale, 200)) ``` - 保持原始比例缩放 ```javascript const scale = Math.min(widthRatio, heightRatio) ``` - 处理滚动条问题 ```css body { overflow: hidden; } ``` 3. **字体处理建议** - 固定字号使用px - 动态字号结合rem+vw ```css .title { font-size: calc(24px + 0.5vw); } ``` 4. **第三方图表库适配** ```javascript // ECharts需主动触发resize window.addEventListener('resize', () => { myChart.resize() }) ``` ### 三、方案对比 | 方案 | 优点 | 注意事项 | |----------------|-----------------------|-----------------------| | vue2-scale-box | 开箱即用 | 需处理iframe嵌套场景 | | CSS transform | 无额外依赖 | 影响部分定位布局 | | rem方案 | 响应式精细控制 | 需全rem单位开发 | [^1]: 安装命令参考vue2-scale-box文档 [^2]: 缩放比例计算逻辑说明
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值