A guide to quickly obtaining the width and height of an element as it resizes in Vue.js

Is there a way to immediately get the width and height of an element when it is resizing in Vue.js? I have created a Codepen illustration and would appreciate any help in making it function correctly, thank you!

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>

Answer №1

If you're looking for instant feedback that reacts to resizing actions in real time, you could consider utilizing a MutationObserver. This allows you to connect it to a specific reference point within your component and monitor any mutations that occur.

The MutationObserver can be attached within the mounted function of your code. Additionally, remember to handle any necessary clean-up operations in the destroyed function.

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>

Answer №2

One simple approach involves using vanilla JavaScript's eventListener to update a local variable

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
}
}

Remember to remove the eventListener when the component is destroyed

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

Answer №3

Excuse my lack of Vue expertise, I am still in the learning process myself. My recommendation would be to take a more modular approach by extracting the boxes and then looping through as many as needed. It is important to note that this method may not be considered best practice, as ideally, the box width and height should come from props and data loaded from the root element.

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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trigger a jQuery event when a particular element has finished loading

Is there a way to globally detect when any element (such as textarea) is displayed on the page in order to perform a specific action? The element could also be added dynamically through an AJAX request. // This code snippet is just an illustration of the ...

Rows in a table will not decrease when added anew

On a page that allows adding and deleting rows from a table of input fields, the following code functions properly for existing fields. However, when attempting to add new rows and delete them in a sequential manner that requires replacing the ID and name ...

Arrange pictures into an array and showcase them

I'm encountering some difficulties with organizing my images in an array and displaying them in a canvas element. Javascript code snippet canvas = document.getElementById('slideshow'); canvasContent = canvas.getContext('2d'); va ...

Whenever I attempt to implement NavigationContainer in react native, an error always pops up

Hey there! I'm currently diving into the world of React Native and decided to start with a small project. However, I've encountered a persistent error when trying to use the NavigationContainer. Here's the error message I keep getting: error ...

What is the best way to access dropdown sub-menu options from a complex multi-level navigation bar

Struggling to figure out how to open my dropdown sub-menu using CSS. Hoping to make it so the user can open it by hovering over the corresponding tag. I attempted to use #lablinksDD to trigger the opening of #ddSbMenu when hovered over #menuDD with #labLin ...

Update database upon drag-and-drop using jQuery

I have a dataset (shown below) that undergoes sorting by 'section'. Each item is placed into a UL based on its section when the page loads. My goal is to automatically update the section in the database when a user drags an item to a different s ...

Using Node.js in conjunction with Nuxt.js: a beginner's guide

I have a server.js file located in the "Server" directory, which is connected to Nuxt.js server.js const express = require('express'); const app = express(); app.get('/api/data', (req, res) => { res.json({ message: 'Hello fr ...

The JSON data parser does not support the use of single quotation marks

Using PHP, I am storing user "comments" from my website in a database and escaping special characters with mysql_real_escape_string(). This helps to avoid any issues with single quotes (') or double quotes ("). To display these comments on the website ...

Toggling event triggers with the second invocation

At this moment, there exists a specific module/view definition in the code: define(['jquery', 'underscore', 'backbone', 'text!templates/product.html'], function($, _, Backbone, productTemplate) { var ProductView = ...

What is the best way to handle errors in the front-end when receiving responses from expressjs?

Here is the issue that I am facing: //express server app.post('/register', (req, res) => { const { password, passwordConfirm } = req.body; if (password === passwordConfirm) { //... } else { ...

Designing a personalized look for a property with Styled-System

Styled-System offers various props related to css grid: I have a suggestion for a new prop, gridWrap. My idea is to allow users to adjust the auto-fit value using the gridWrap prop. Here's the base CSS code: grid-template-columns: repeat(auto-fit, mi ...

Modify the text of a button in Angular to be underlined after it has

Is it possible to avoid DOM manipulation in the controller and keep it focused on business logic? I have a scenario with three buttons where I want to underline the text of the button when clicked. Here is a link to a demo: jsfiddle CSS: .underline { te ...

Transfer the value of a variable within the local scope to the dragstart event handler during the dynamic generation of an input element

After going through several similar questions, I couldn't find a solution that applies to my specific case. Here is the loop I am working with: $.each(data.modules, function(i, field) { let $li = $(`<li><div> Name: ${field.name}</div& ...

Change not accepted

I am a beginner in Angular and still grappling with the fundamentals. On my menu, I have a cart icon with an initial value of 0 upon first load. In my product list, each product has an 'AddToCart' button. What I aim to achieve is- I want to dy ...

Tips for avoiding page reloading with the use of vue, vue recaptcha, and axios

My experience with Vue and coding, in general, has gotten rusty. Currently, I'm tackling a small project that involves a form communicating with Python on the backend. While the backend part seems to be covered (knock on wood), the front end is giving ...

Utilize the @blur event within flatpickr to trigger actions when the output is empty

<b-col md="7" offset-md="1"> <b-form-group> <template> Date and Time <flat-pickr id="datetime" v-model="datetime" class="form-control" ...

The update of data has encountered a hurdle with Mongoose

Is there a way to update user data without having to fill out all the fields? For instance, if I only input the name, only the name should be updated while keeping other values the same. However, when I attempted this, my password validation displayed an e ...

Utilizing vuex methods within a promise

I'm having trouble grasping this conceptually. In my attempt to utilize a Vuex store action within a second .then() function of a promise ( this.$store.dispatch('setAdditionalUserInfo', doc.data())) , I encountered the error message: TypeEr ...

Avoiding metacharacters and utilizing them as a string variable for selection

For example, I have a variable called myid, and its value is "abc xyz". Then, I use a function to escape metacharacters and assign the result to another variable like this: var x = "#"+escapechars(myid);. The evaluated value of x is #abc\\xyz. ...

Managing the ajax response to showcase a button within datatables

Here is my current datatable structure: <table id="list" class="display" width="100%" > <thead> <tr> <th>Title</th> <th>Description</th> <th>delete</th> ...