Currently I trigger an event to take the same height of the current element when the component is mounted, however this doesn't always work since it is sent once and if the element is resized it won't get sent again. Also I need to put a timeout since sometimes the chart in the componenet change sthe height after the ajax call.
How do I send this event ANYTIME the height of the current element is changed?
This is what I am currently doing:
mounted: function() {
setTimeout(function() {
this.$emit('resize', this.$el.offsetHeight);
},1000);
}
There is more Vue style solution based on ResizeObserver, but not supported in all browsers - yet
DOC: https://caniuse.com/#feat=resizeobserver
Examplum
data () {
return {
ro: null,
}
},
methods: {
onResize () {
this.$emit('resize', this.$refs.myElement.offsetHeight)
},
},
mounted () {
this.ro = new ResizeObserver(this.onResize)
this.ro.observe(this.$refs.myElement)
},
beforeDestroy () {
this.ro.unobserve(this.$refs.myElement)
}
Until ResizeObserver becomes standard, you can use MutationObserver to keep track of the element's size. Codepen link
new Vue({
el: "#app",
data() {
return {
width: null,
height: null,
observer: null
};
},
mounted() {
//get initial dimensions. Mutation observer will observe mutations only
const box = this.$refs.box,
boxSize = box.getBoundingClientRect();
this.width = Math.trunc(boxSize.width) + "px";
this.height = Math.trunc(boxSize.height) + "px";
// initialize the observer on mount
this.initObserver();
},
//disconnect the observer before destroy
beforeDestroy() {
if (this.observer) this.observer.disconnect();
},
methods: {
initObserver() {
const box = this.$refs.box,
vm = this,
config = {
attributes: true
};
// create the observer
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
// check if the mutation is attributes and update the width and height data if it is.
if (mutation.type === "attributes") {
let {
width,
height
} = box.style;
vm.width = width;
vm.height = height;
}
});
});
// observe element's specified mutations
observer.observe(box, config);
// add the observer to data so we can disconnect it later
this.observer = observer;
}
}
});
.box {
text-align: center;
font-family: Arial;
box-sizing: border-box;
width: 150px;
height: 150px;
border: 2px solid red;
padding: 10px;
margin: 0 auto;
resize: both;
overflow: auto;
}
.size {
color: #2a9966;
font-weight: 600;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<!-- more info on refs: https://vuejs.org/v2/api/#ref -->
<div class=" box" ref="box">
<h4>Resize Me</h4>
<p>
<span>width: </span><span class="size">{{ width }}</span>
</p>
<p>
<span>height: </span><span class="size">{{ height }}</span>
</p>
</div>
</div>
I've had some issues getting ResizeObserver
to work in a Vue2 TypeScript project. Two approaches worked with (AFAICT) identical results:
Using the resize-observer-polyfill (which essentially wraps MutationObserver
). This required an import ResizeObserver from 'resize-observer-polyfill'
in my component.
Installing the @types/resize-observer-browser
npm package, based on this answer, and adding an entry to my tsconfig.json
:
{
"compilerOptions": {
...
"types": [
...
"resize-observer-browser"
]
}
}
This second approach didn't require any additional import and is the solution I'm favouring.
Both approaches offer the same ResizeObserver
API, e.g.
this.resizeObserver = new ResizeObserver((entries, observer) => {
log("Resize called", entries, observer)
})
this.resizeObserver.observe(this.$refs.canvas as Element)
(note: only tested in Chrome 88, Feb 2021)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With