Issue
I have a Vue component, which has the class "tab-body-wrapper" whose purpose is to display the "slot" for whichever tab is currently active.
After troubleshooting, it appears that this ".tab-body-wrapper" component, which I have set a height of 100% in my CSS, reduces in height during the v-if re-render even though the height of the element that contains it (".sub-menu-tabs-body") remains exactly the same at the same point in time.
My Vue component (with class of "tab-body-wrapper")
Vue.component("tab", {
template: `
<div v-if="isActive"
class="tab-body-wrapper">
<slot></slot>
</div>
`,
props: {
name: { required: true },
icon: { required: true },
selected: { default: false }
},
data() {
return {
isActive: false
}
},
mounted() {
this.isActive = this.selected;
}
});
The red arrow below shows where this Vue component resides within the DOM
The relevant CSS
.sub-menu-tabs-wrapper,
.sub-menu-tabs-body,
.tab-body-wrapper {
height: 100%;
}
The way I troubleshot my problem was by placing the following code in the mounted() hook of my other Vue component, which is contained in the slot of the above Vue component.
Below is the troubleshooting code in the mounted hook of my other Vue component, which resides in the slot. Note that I also used getBoundingClientRect and the results were the same so the issue is not with d3.
console.log(d3.select(".sub-menu-tabs-wrapper").style("height"));
console.log(d3.select(".sub-menu-tabs-body").style("height"));
console.log(d3.select(".tab-body-wrapper").style("height"));
On initial render, the heights were as expected:
scripts.js:791 1207px // .sub-menu-tabs-wrapper
scripts.js:792 1153px // .sub-menu-tabs-body
scripts.js:793 1151px // .tab-body-wrapper
However, upon clicking away and then clicking back onto the tab, you can see that the containing element (".sub-menu-tabs-body") retains its height of 1153px but ".tab-body-wrapper" has shrunk to 574.5px.
scripts.js:791 1207px // .sub-menu-tabs-wrapper
scripts.js:792 1153px // .sub-menu-tabs-body
scripts.js:793 574.5px // .tab-body-wrapper
What's stranger is that when I console.log the height of ".tab-body-wrapper" afterwards, I get 1151px.
For some context, the reason why I need the height of ".tab-body-wrapper" to be correct during the render is because I have a bunch of d3 charts that use the height and width of elements within ".tab-body-wrapper" during the render to determine their respective height and width. As such, the issue I am having is causing these charts to render with the incorrect height and width.
Note that using v-show for my tab component is not an option for reasons I will not go into here.
Solution
Try wrapping the calculation in a this.$nextTick()
callback. As stated by the docs it will:
Defer the callback to be executed after the next DOM update cycle
so the element is correctly rendered when executing it.
new Vue({
el: '#app',
data: {
pRect: 0
},
mounted() {
this.$nextTick(() => {
this.pRect = document.querySelector('p').getBoundingClientRect();
})
}
})
<script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script>
<body>
<div id="app">
<p>My BoundingClientRect is: {{ pRect }}<p>
</div>
</body>
Answered By - yuriy636
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.