菜单栏缩放展开和页面全屏时不刷新页面重新渲染(适配不同浏览器)

获取祖先盒子的宽度,监听祖父元素的宽度,只有宽度变化时才重新挂载
ResizeObserver 是原生 JavaScript 提供的 API,用来监听一个 DOM 元素 尺寸的变化(宽度、高度)。
window.onresize 不同,它可以监听具体某个元素,而不仅仅是整个浏览器窗口。
data(){
   showChart: true,
   prevWidth: 0
},
mounted() {
    const el = this.$refs.dashboard;
    if (el) {
      this.prevWidth = el.offsetWidth; // 初始化宽度
      // 创建 ResizeObserver 实例
      this.resizeObserver = new ResizeObserver((entries) => {  //entries 是一个数组,包含了所有发生变化的元素的尺寸信息对象
        const newWidth = entries[0].contentRect.width;
        if (newWidth !== this.prevWidth) { // 只有宽度变化时才重新挂载
          // console.log('宽度从', this.prevWidth, '变为', newWidth);
          this.prevWidth = newWidth;
          this.remountChart(); // 宽度变化时重新挂载组件
        }
      });
      // 开始监听
      this.resizeObserver.observe(el);
    }
宽度变化时重新挂载组件,通过v-if来控制盒子或组件Dom元素销毁和创建,通过this.$nextTick()等 DOM 更新完成之后,再把 showChart 设置为 true,防止组件不刷新
remountChart() {
      this.showChart = false;
      this.$nextTick(() => {
        this.showChart = true;
      });
    }
附加功能:全屏效果
适配常见浏览器并更新
handleFull() {
      const elem = this.$refs.dashboard; // 这里是整个页面的根元素
      if (elem.requestFullscreen) {
        elem.requestFullscreen();
      } else if (elem.mozRequestFullScreen) { // Firefox
        elem.mozRequestFullScreen();
      } else if (elem.webkitRequestFullscreen) { // Chrome, Safari 和 Opera
        elem.webkitRequestFullscreen();
      } else if (elem.msRequestFullscreen) { // IE/Edge
        elem.msRequestFullscreen();
      }
      this.remountChart()
    },
考虑到:菜单栏缩放展开和全屏时会触发多次监听,频繁的 remountChart() 导致性能下降,采用防抖来处理。并在组件销毁时清理监听,防止内存泄漏。
const el = this.$refs.dashboard;
    if (el) {
      this.prevWidth = el.offsetWidth; // 初始化宽度
      // 创建 ResizeObserver 实例
      // 尺寸变化回调(带防抖)
      const handleResize = this.debounce((entries) => {
        const newWidth = entries[0].contentRect.width;
        if (newWidth !== this.prevWidth) {
          console.log('宽度从', this.prevWidth, '变为', newWidth);
          this.prevWidth = newWidth;
          this.remountChart(); // 重新挂载图表组件
        }
      }, 200);
      // 创建 ResizeObserver 实例
      this.resizeObserver = new ResizeObserver(handleResize);
      // 开始监听
      this.resizeObserver.observe(el);
    }
防抖函数
    debounce(fn, delay) {
      let timer = null;
      return function (...args) {
        if (timer) clearTimeout(timer);
        timer = setTimeout(() => {
          fn.apply(this, args);
        }, delay);
      };
    },
清理监听
beforeDestroy() {
    // 清理监听
    this.resizeObserver && this.resizeObserver.disconnect();
    this.resizeObserver = null;
    window.removeEventListener('resize', this.onResize);
  },
 
posted @ 2025-06-04 10:25  Happy-P  阅读(19)  评论(0)    收藏  举报