How to get the element width and height immediately when it resizing in Vue.js? Here is my code pen illustration please help me to change it till work,thanks!
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=".4.4/vue.js"></script>
<div id="app">
<div v-for="box,key in boxs" class="resize">
{{ box.width }} x {{ box.height }}
</div>
</div>
How to get the element width and height immediately when it resizing in Vue.js? Here is my code pen illustration please help me to change it till work,thanks!
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./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>
Share
Improve this question
edited Jan 23, 2018 at 15:38
zero298
26.9k10 gold badges79 silver badges107 bronze badges
asked Sep 18, 2017 at 9:21
FanFan
1,1804 gold badges17 silver badges35 bronze badges
3 Answers
Reset to default 8To get immediate feedback that responds to the actual resize action, you might want to try using a MutationObserver
. You can attach it to a ref
point of your ponent and listen for mutations there.
You can attach the MutationObserver
in the mounted
function. Be sure to also do any cleanup that you need 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",
ponents: {
"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./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>
Easy way would be plain JS eventListener
to change 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
}
}
and don't forget to remove the eventListener
on ponent destroy
beforeDestroy() {
window.removeEventListener('resize', this.getWindowWidth);
}
Forgive me, but I'm still learning Vue as well. I'd suggest you do more modular approach and extract the boxes, then just loop how many you want. Please note that this is not best-practice, as the box w/h should probably be ing from props and data being loaded from the root element.
const box = Vue.ponent("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",
ponents: { 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./ajax/libs/vue/2.5.2/vue.js"></script>
<div id="app">
<div v-for="b in [0,1]">
<box></box>
</div>
</div>