一行指令实现大屏元素分辨率适配(Vue)

简介: 一行指令实现大屏元素分辨率适配(Vue)

一行指令实现大屏元素分辨率适配(Vue)


前言


随着前端技术的不断发展、数据中心(中台)之类的概念的不断升级、物联网设备的更新和普及,越来越多的业主(项目)喜欢在系统中添加一个或者多个可视化大屏,用来集中的展现数据变化、位置变化等等,老板们也更喜欢称之为“态势”。


当然,作为程序员一般都不关心“老板们”的想法,只要完成项目即可。但是经常会有这样的问题:我有一个大屏的模板,但是用户的浏览器分辨率不够,或者有的有书签栏有的没有书签栏,更或者是有的全屏了有的只是小窗口,这样就有了代码对不同分辨率场景下的适配需求了。


1. 常见的适配方案


平时我们使用的 web 端的适配方案,主要有以下几种:


  1. vw/vh 配合百分比实现,让元素根据窗口大小进行自动调整


  1. fontSize 配合 rem 实现“单位宽度”的统一


  1. 根据不同的分辨率范围调整页面布局


  1. 版心布局,配合最小宽度


目前大多数屏幕适配方案的原理都是采用的以上的几种方式,但是这几种方式也有很大的弊端:浏览器文字有最小尺寸!


在一般的 1080p 及以上的分辨率的屏幕中,大多数设计图的比例和显示效果都能完美还原。但如果某个系统的页面内容太多,或者浏览器部分使用的分辨率(不是物理分辨率)达不到完整显示的要求,采用上面的几种方式就有可能造成 文字的计算大小小于浏览器的最小字体大小,此时就有可能因为文字宽度超出元素而导致页面样式崩溃。


版心布局配合最小宽度可以保证显示效果,但是不适合大屏项目。


2. CSS3 缩放方案


在上面的几种方案都不满足时,大家一般就会采用另外一种方案:CSS3 scale 缩放。

通过计算设计图尺寸比例与实际的页面显示区域大小,来动态调整元素的缩放比例。


个人认为这是针对小分辨率情况下保留显示内容及样式最好的一种处理方式。


当然,这种方式依然有一些弊端:


  1. 缩放后可能会造成边缘显示模糊


  1. 如果内部存在 canvas 元素,可能导致 canvas 内部的内容渲染失真


  1. 高德地图 1.x 会导致事件坐标偏移 (2.0 已经修复)


  1. ...


3. 封装一个缩放指令


这里简单回顾一下 Vue 的自定义指令:通过配置自定义指令和绑定参数,在组件/元素加载、更新、销毁等不同时期执行对应的处理逻辑。


Vue 的自定义指令包含一下几个钩子函数:


  • bind: 解析到指令绑定时执行,仅执行一次


  • inserted: 插入父节点时执行


  • update:组件触发更新时执行


  • componentUpdated:所有组件更新结束之后执行


  • unbind:元素解绑(销毁)时执行,也只执行一次


这里因为我们只需要在初始化时绑定浏览器的 resize 事件来调整元素缩放,所以只需要配置 inserted 即可;当然,为了优化代码逻辑,减少资源消耗等情况,也需要在 unbind 阶段去取消 resize 事件的一个回调函数。


代码如下:


// 缩放指令
import Vue from "vue";
function transformScale(el, options) {
  const { target = "width", origin = "top left" } = options;
  Vue.nextTick(() => {
    // 获取显示区域高宽
    const width = window.innerWidth;
    const height = window.innerHeight;
    el.style.transformOrigin = origin;
    if (target === "ratio") {
      const scaleX = width / CONF.width;
      const scaleY = height / CONF.height;
      el.style.transform = `scaleX(${scaleX}) scaleY(${scaleY})`;
    } else {
      let scaleProportion = 1;
      if (target === "width") {
        scaleProportion = width / CONF.width;
      }
      if (target === "height") {
        scaleProportion = height / CONF.height;
      }
      el.style.transform = `scale(${scaleProportion})`;
    }
  });
}
function inserted(el, binding) {
  const options = binding.options || { passive: true };
  const callback = () => transformScale(el, binding.value);
  window.addEventListener("resize", callback);
  callback();
  el._onResize = {
    callback,
    options
  };
}
function unbind(el) {
  if (!el._onResize) {
    return;
  }
  const { callback } = el._onResize;
  window.removeEventListener("resize", callback);
  delete el._onResize;
}
export const Scale = {
  inserted,
  unbind
};
export default Scale;


说明:


  1. 指令接收一个对象参数,用来指定比例计算方式和缩放定位


  1. 需要一个全局配置 CONF 对象,用来指定默认的页面尺寸


  1. 为了保证页面已经加载完,能获取到 dom 元素,需要调用 Vue.nextTick


  1. 需要销毁监听事件


整个代码其实很简单,就是通过监听 resize 事件去调整元素的缩放比例。


但是这里我也做了一点小的配置,用来适应更多的情况:


  1. 接收一个 target 配置,用来确认比例计算方式;可以以宽度或者高度作为统一的缩放标准,也可以分别计算


  1. 接收 transform 的 origin 配置,保证不同位置的元素可以缩放到不同的位置,避免缩放偏移


  1. 不涉及绑定元素的尺寸,只需要默认尺寸即可;写代码时可以直接根据设计图配置元素尺寸


4. 后记


当然,这个指令不能说有多完美,依然有很多有漏洞的地方,比如没有防抖、缩放不会改变css指定的尺寸,容易出现滚动条等;并且因为之前的项目中还涉及到很多图表、地图,也经常导致一些显示问题,所以后面有增加了一些新的指令,但是分辨率适配这个问题还是要根据实际情况来确定具体的方案。


目录
相关文章
|
3天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
4天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
4天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
4天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
3天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
|
5天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
|
3天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。自学前端2年半,熟悉JavaScript与Vue,正向全栈方向发展。博客内容涵盖Vue基础、列表展示及计数器案例等,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
|
17天前
|
数据采集 监控 JavaScript
在 Vue 项目中使用预渲染技术
【10月更文挑战第23天】在 Vue 项目中使用预渲染技术是提升 SEO 效果的有效途径之一。通过选择合适的预渲染工具,正确配置和运行预渲染操作,结合其他 SEO 策略,可以实现更好的搜索引擎优化效果。同时,需要不断地监控和优化预渲染效果,以适应不断变化的搜索引擎环境和用户需求。
|
5天前
|
存储 JavaScript
Vue 组件间如何通信
Vue组件间通信是指在Vue应用中,不同组件之间传递数据和事件的方法。常用的方式有:props、自定义事件、$emit、$attrs、$refs、provide/inject、Vuex等。掌握这些方法可以实现父子组件、兄弟组件及跨级组件间的高效通信。
|
10天前
|
JavaScript
Vue基础知识总结 4:vue组件化开发
Vue基础知识总结 4:vue组件化开发