Reputation: 442
I have a component that needs to calculate some values using the DOM, and so I have the onMounted()
lifecycle hook. In onMounted()
I calculate some values (technically, they're computed properties) dependent on DOM elements.
I then use the values found in another computed property, leftOffset
. I need to use leftOffset
in template
(it changes some CSS, not really relevant).
Below is my setup()
:
setup() {
let showContent = ref(false);
let windowWidth = ref(null);
let contentHider = ref(null);
let contentHiderXPos ;
let contentHiderWidth ;
let leftWidth;
onMounted(() => {
// The DOM element will be assigned to the ref after initial render
windowWidth = ref(window.innerWidth);
contentHiderXPos = computed(() => contentHider.value.getBoundingClientRect().left);
contentHiderWidth = computed(() => contentHider.value.getBoundingClientRect().width);
leftWidth = computed(() => contentHiderXPos.value + contentHiderWidth.value);
});
let leftOffset = computed(() => {
return -(windowWidth.value - leftWidth.value)
});
return {
contentHider,
leftOffset,
}
contentHider
references a the DOM element of one of the divs defined in template
.
My problem that leftOffest.value
is undefined, because it tries to access windowWidth.value
and leftWidth.value
, which are also undefined. I've also tried putting leftOffset
inside onMounted()
, but then I can't access it from template
(it's undefined).
How can I re-structure my code so that leftOffset
can both be accessed from template
and can also access the values found in onMounted()
?
I've searched online, but couldn't find anything specific to the composition API.
Upvotes: 0
Views: 1174
Reputation: 744
Your usage of the ref
is wrong. Follow the comments in the below snippet.
Also this is assuming that you do not want the window.innerwidth to be reactive.
// dont create another ref => you are trying to assign a new object here, thus breaking the reactivity
// windowWidth = ref(window.innerWidth);
// do this instead
windowWidth.value = window.innerWidth
If you want the innerWidth
to be reactive, you have to use the native event listener like this;
const windowWidth = ref(window.innerWidth)
onMounted(() => {
window.addEventListener('resize', () => {windowWidth.value = window.innerWidth} )
})
onUnmounted(() => {
window.removeEventListener('resize', () => {windowWidth.value = window.innerWidth})
})
Upvotes: 1