如何在Vue.js中实时获取元素的宽度和高度变化

3
如何在Vue.js中实时获取元素的宽度和高度?以下是我的代码示例,请帮我修改以使其正常工作,谢谢! 请点击Codepen查看。

let app = new Vue({
  el: '#app',
  data: {
    boxs: [{
        width: 100,
        height: 100
      },
      {
        width: 100,
        height: 100
      }
    ]
  }

});
#app {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}

.resize {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 5px;
  width: 100px;
  height: 100px;
  overflow: hidden;
  resize: both;
  background-color: #C3E2CE;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.js"></script>
<div id="app">
  <div v-for="box,key in boxs" class="resize">
    {{ box.width }} x {{ box.height }}
  </div>
</div>

3个回答

8
为了获得响应实际调整大小操作的即时反馈,您可以尝试使用MutationObserver。您可以将其附加到组件的ref点上并在那里监听变异。 您可以在mounted函数中附加MutationObserver。请确保在destroyed函数中进行任何所需的清理工作。

const Resizable = {
  template: "<div ref='main' @resize='onResize' class='resize'>{{dims.width}} | {{dims.height}}</div>",
  data() {
    return {
      dims: {
        width: null,
        height: null
      }
    };
  },
  mounted() {
    const {
      width,
      height
    } = this.$refs.main.getBoundingClientRect();

    this.dims.width = width;
    this.dims.height = height;

    const mutationHandler = mutationList => {
      for (let mutation of mutationList) {
        if (mutation.type === "attributes") {
          const {
            width,
            height
          } = mutation.target.getBoundingClientRect();

          this.dims.width = width;
          this.dims.height = height;
        }
      }
    };
    const mo = new MutationObserver(mutationHandler);

    mo.observe(this.$refs.main, {
      attributes: true,
      childList: true,
      subtree: true
    });

  },
  methods: {
    onResize() {
      console.log("Resized");
    }
  }
};

const app = new Vue({
  el: "#app",
  components: {
    "resizable": Resizable
  },
  data() {
    return {
      items: [
        "foo",
        "bar",
        "fizz"
      ]
    }
  }
});
body {
  background-color: #414141;
}

.container {
  display: flex;
  align-items: center;
  justify-content: center;
}

.resize {
  resize: both;
  margin: 5px;
  width: 100px;
  height: 100px;
  color: black;
  overflow: scroll;
  background-color: white;
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.js"></script>

<div id="app">
  <div class="container">
    <resizable v-for="item in items" :key="item" class="resize"></resizable>
  </div>
</div>


4

简单的方法是使用普通 JS eventListener 来更改本地变量

window.addEventListener('resize', this.getWindowWidth);

data() {
  return {
    windowWidth:0
  }
},
mounted () {
  this.$nextTick(function() {
    window.addEventListener('resize', this.getWindowWidth);
    this.getWindowWidth()
  })
},
methods: {
getWindowWidth() {
  this.windowWidth = document.documentElement.clientWidth
}
}

同时不要忘记在组件销毁时移除eventListener

beforeDestroy() {
  window.removeEventListener('resize', this.getWindowWidth);
}

0

不好意思,但我也还在学习Vue。我建议你采用更模块化的方法,将这些方框提取出来,然后根据需要进行循环。请注意,这并不是最佳实践,因为方框的宽高应该从props中获取,并且数据应该从根元素加载。

const box = Vue.component("box", {
  template: '<div class="resize">{{ boxWidth }} x {{ boxHeight}}</div>',
  data() {
    return {
      boxWidth: 100,
      boxHeight: 100,
    };
  },
  mounted: function() { 
    this.$el.addEventListener("mouseup", this.move);
  },
  methods: {
    move(e) {
      if (e.target == this.$el) {
        this.boxWidth = parseInt(this.$el.style.width);
        this.boxHeight = parseInt(this.$el.style.height);
      }
    }
  }
});

let app = new Vue({
  el: "#app",
  components: { box: box },
});
#app {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}

.resize {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 5px;
  width: 100px;
  height: 100px;
  overflow: hidden;
  resize: both;
  background-color: #C3E2CE;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.js"></script>
<div id="app">
    <div v-for="b in [0,1]">
      <box></box>
    </div>
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接