深入掌握Vue.js中window.onresize事件的使用方法

边中之城 2025-01-01 10:40:59编程技术
120

在现代Web开发中,响应式设计已成为不可或缺的一部分。随着屏幕尺寸和设备种类的多样化,确保网页在各种环境下都能良好展示变得尤为重要。Vue.js作为一款流行的前端框架,提供了丰富的工具和方法来实现响应式布局。其中,window.onresize事件在处理窗口大小变化时扮演着关键角色。本文将深入探讨Vue.js中window.onresize事件的使用方法,结合具体实例,帮助开发者更好地掌握这一技术,提升用户体验。

前言

最近做的项目老是涉及到大小屏切换,但是因为屏幕宽高不一样的原因,老是要计算表格高度

window.onresize:监听window窗口变化,当窗口大小发生变化时,会触发此事件

含义

MDN中的定义是这样子的:

文档视图调整大小时会触发 resize事件。

在js中使用

window.onresize = function(){
	// todo event
}

在html中使用

<body onresize="myFunction()">

在vue中的使用

需要注意的是,this在函数中指的是window,而不是vue实例

mounted(){
	const _this = this
	window.onresize = function(){
		_this.width = document.body.clientWidth
		// todo event
	}
}

需要注意的两点:

1、this在函数中不可用,他在函数中不一定指全局上下文

解决办法如下:

const  _this = this
window.onresize = function(){
	_this.width = document.body.clientWidth
}

2、在谷歌浏览器中,window.onresize会触发两次,网上说是谷歌浏览器的bug

解决办法如下,设定一个标识

	let flag = true
    window.onresize = function () {
      if (flag) {
        console.log(new Date(), '窗口改变了')
        flag = false
      }
      let timeId = setTimeout(() => {
        flag = true
        timeId = null // 清除延时定时器
      }, 1000)
    }

没使用flag之前

深入掌握Vue.js中window.onresize事件的使用方法

使用之后,如下图,控制台只打印了一遍

深入掌握Vue.js中window.onresize事件的使用方法

注意在项目中的使用

1、window.onresize只能在一个组件中使用,如果多个组件调用则会出现覆盖情况,所以我的解决方案是在App.vue中使用,获取document.documentElement.clientWidth(即浏览器宽度)存放在vuex中,别的组件只需要用computed(计算属性)将vuexclientWidth获取,然后通过watch监听clientWidth的值,即可触发组件事件

2、由于window.onresize是全局事件,在其他页面改变界面时也会执行,这样可能会出现问题,需要在出这个界面时注销window.onresize事件。

created() {
    this.$bus.$on('resize', this.$_setTableHeight)
    window.onresize = function () {
      console.log(new Date(), '窗口改变了')
    }
},
beforeDestroy() {
    this.$bus.$off('resize', this.$_setTableHeight)
    window.onresize = null
},

注销之后,切换到其他页面,控制台就不会输出以下信息

深入掌握Vue.js中window.onresize事件的使用方法

window.addEventListener

mounted() {
    this.$nextTick(() => {
      this.onDrawLine()
      window.addEventListener('resize', this.resize())
    })
  },
 beforeDestroy() {
    console.log('删除了')
		// 具名函数使用removeEventListener清除,但是匿名函数不行
    window.removeEventListener('resize', this.resize())
 },

性能优化

window.onresize 在监听窗口变化时,固然起到很好的效果,但是对于网页性能消耗过大。因为html中每个标签的变化,都会触发window.onresize 事件,比如显示/隐藏某个抽屉、添加/删除某个div等等,很有可能会造成循环触发和无限制触发,于是新推出了另外一个事件**ResizeObserver(对element和svgelement元素进行监听)**

MDN定义如下:

ResizeObserver避免了通过回调函数调整大小时,通常创建的无限回调循环和循环依赖项。它只能通过在后续的帧中处理 DOM 中更深层次的元素来做到这一点。如果它的实现遵循规范,则应在绘制前和布局后调用 resize 事件。

MDN示例:https://mdn.github.io/dom-examples/resize-observer/resize-observer-text.html

部分源码如下:

const h1Elem = document.querySelector('h1');
const pElem = document.querySelector('p');
const divElem = document.querySelector('body > div');
const slider = document.querySelector('input[type="range"]');
const checkbox = document.querySelector('input[type="checkbox"]');

divElem.style.width = '600px';

slider.addEventListener('input', () => {
  divElem.style.width = `${slider.value}px`;
})

const resizeObserver = new ResizeObserver((entries) => {
  for (const entry of entries) {
    if (entry.contentBoxSize) {
      // Firefox implements `contentBoxSize` as a single content rect, rather than an array
      const contentBoxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;

      h1Elem.style.fontSize = `${Math.max(1.5, contentBoxSize.inlineSize / 200)}rem`;
      pElem.style.fontSize = `${Math.max(1, contentBoxSize.inlineSize / 600)}rem`;
    } else {
      h1Elem.style.fontSize = `${Math.max(1.5, entry.contentRect.width / 200)}rem`;
      pElem.style.fontSize = `${Math.max(1, entry.contentRect.width / 600)}rem`;
    }
  }

  console.log('Size changed');
});

resizeObserver.observe(divElem);

checkbox.addEventListener('change', () => {
  if (checkbox.checked) {
    resizeObserver.observe(divElem);
  } else {
    resizeObserver.unobserve(divElem);
  }
});

副作用:兼容性不强,有些浏览器兼容,具体情况见Can I Use

参考链接:

  • https://www.cnblogs.com/yxysuanfa/p/6878016.html

  • https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver

总结

通过本文的介绍,我们详细了解了Vue.js中window.onresize事件的使用方法及其在响应式设计中的重要性。我们学习了如何在Vue组件中正确绑定和解绑window.onresize事件,避免内存泄漏和性能问题。同时,我们也探讨了如何利用Vuex在多个组件间共享窗口尺寸数据,实现更高效的状态管理。希望这些技巧和最佳实践能帮助你在未来的项目中更加得心应手地处理响应式布局,为用户提供更优质的浏览体验。

Vue.js window.onresize
THE END
蜜芽
故事不长,也不难讲,四字概括,毫无意义。

相关推荐

ElementUI:饿了么前端团队开源的一套基于 Vue.js 的桌面端组件库
ElementUI 是饿了么前端团队开发的一套基于 Vue.js 的桌面端组件库。其提供了一系列经过精心设计和测试的 UI 组件,涵盖了从基本的输入框、按钮到复杂的表格、导航菜单等各个...
2024-11-01 编程技术
350

如何利用Nginx部署Vue.js前端项目
在这篇文章中,我们将深入探讨如何使用 Nginx 部署一个 Vue.js 前端项目。Vue 是一个流行的前端 JavaScript 框架,而 Nginx 则是一个性能卓越的 Web 服务器和反向代理服务器。...
2024-09-04 编程技术
196

2024年十大热门 Vue.js 界面组件UI库
Vue.js之所以受到青睐,很大一部分原因是其庞大的生态系统,特别是众多的UI库,这些库提供了预先构建的组件和工具,帮助开发者快速高效地构建出既美观又响应迅速的用户界面。...
2024-04-02 编程技术
87

尤雨溪:Vue 2 生命周期已正式结束,开发团队应迁移至最新版本或购买扩展支持
1 月 2 日消息,Vue.js作者尤雨溪发文声称,Vue 2已于2023年12月31日结束生命周期(EOL),目前 Vue 2 已经无法接收到新功能及修复补丁,还在使用Vue 2的开发团队应迁移至最新的...
2024-01-02 新闻资讯
51