You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Alpine.js中Resize Observer无法更新数据的问题求助

Alpine.js中Resize Observer数据无法实时更新的解决方法

使用Resize Observer监听元素尺寸变化,尝试更新Alpine.js的dimensions数组并在页面展示,但数据仅初始化时显示一次,窗口调整尺寸时无法更新。

原代码

JavaScript

function app() {
  return {
    init() {
      var ro = new ResizeObserver((entries) => {
        for (let entry of entries) {
          console.log(entry);
          this.dimensions.push({
            dim: `${(entry.contentRect.width / 16).toFixed(2)}rem`
          });
        }
      });
      ro.observe(this.$refs.box);
      ro.observe(document.documentElement);
    },
    dimensions: [],
    display: []
  };
}

HTML

<div class="color"></div>
<div class="wrapper" x-data="app()">
  <p class="dimension" x-text="dimensions[1].dim"></p>
  <div class="box">
    <p class="dimension" x-text="dimensions[0].dim" x-ref="box"></p>
    <pre class="code">margin-inline: max(0px,((100% - 64rem) / 2))</pre>
  </div>
</div>

问题原因

每次触发Resize Observer回调时,代码都往dimensions数组push新元素,但页面绑定的是固定索引(dimensions[0]、dimensions[1]),因此只会显示第一次push的元素,后续新增的元素不会被页面绑定的表达式读取到。

解决方案

不要通过push新增元素,而是直接替换数组对应索引的元素;或者更简洁地使用独立变量存储每个元素的尺寸,避免数组索引绑定的问题。

方案1:修改数组元素而非新增

function app() {
  return {
    init() {
      const ro = new ResizeObserver((entries) => {
        entries.forEach((entry, index) => {
          // 替换对应索引的元素,确保页面绑定的表达式能读取到最新值
          this.dimensions[index] = {
            dim: `${(entry.contentRect.width / 16).toFixed(2)}rem`
          };
        });
      });
      ro.observe(this.$refs.box);
      ro.observe(document.documentElement);
    },
    // 初始化数组长度为2,对应两个监听元素
    dimensions: [{}, {}],
    display: []
  };
}

方案2:使用独立变量(推荐)

如果不需要保存历史尺寸数据,用独立变量存储更清晰:

function app() {
  return {
    boxDim: '',
    htmlDim: '',
    init() {
      const ro = new ResizeObserver((entries) => {
        entries.forEach(entry => {
          const remValue = `${(entry.contentRect.width / 16).toFixed(2)}rem`;
          // 根据目标元素区分赋值
          if (entry.target === this.$refs.box) {
            this.boxDim = remValue;
          } else if (entry.target === document.documentElement) {
            this.htmlDim = remValue;
          }
        });
      });
      ro.observe(this.$refs.box);
      ro.observe(document.documentElement);
    }
  };
}

对应的HTML修改为:

<div class="color"></div>
<div class="wrapper" x-data="app()">
  <p class="dimension" x-text="htmlDim"></p>
  <div class="box">
    <p class="dimension" x-text="boxDim" x-ref="box"></p>
    <pre class="code">margin-inline: max(0px,((100% - 64rem) / 2))</pre>
  </div>
</div>

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 11:20:35