I am trying out the composition api in vueJs 3. Unfortunately I don't know how to include my mounted code in the setup(). When I put the code into the setup, the javascript tries to access the not yet rendered DOM. Can anyone tell me how I have to rewrite this?
Option api sytle (works)
<script>
export default {
name: "NavBar",
data() {
return {};
},
methods: {},
mounted() {
const bm = document.querySelector('#toggle');
const menu = document.querySelectorAll('nav ul li');
const overlay = document.querySelector('#overlay');
// ...
bm.addEventListener('click', () => {
bm.classList.toggle("active");
overlay.classList.toggle("open");
})
},
}
</script>
<template>
<header>
<div class="button_container" id="toggle">
<span class="top"></span>
<span class="middle"></span>
<span class="bottom"></span>
</div>
<div class="overlay" id="overlay">
<nav class="overlay-menu">
<ul>
<li><a href="#home">Home</a></li>
<!-- ... -->
</ul>
</nav>
</div>
</header>
</template>
document.querySelector(), see how to bind events in vue3// bad
<div class="button_container" id="toggle">...</div>
mounted() {
const bm = document.querySelector('#toggle');
bm.addEventListener('click', () => {
bm.classList.toggle("active");
overlay.classList.toggle("open");
})
}
// good
<div class="button_container" id="toggle" @click="toggleContainer">...</div>
methods: {
toggleContainer() {
...
}
}
document.querySelector() in setup(), you can use onMountedimport { onMounted } from 'vue';
export default {
setup() {
onMounted(() => {
const bm = document.querySelector('#toggle');
bm.addEventListener('click', () => {
bm.classList.toggle("active");
overlay.classList.toggle("open");
})
});
}
}
// or inside <script setup>
import { onMounted } from 'vue';
onMounted(() => {
....
});
But, just as @kissu commented, ref is a better way if you have to handle the html tag directly in vue
<div
ref="toggler">
...
</div>
<script setup>
import { ref, onMounted } from 'vue';
const toggler = ref(null);
onMounted(() => {
console.log(toggler.value) // <div></div>
});
</script>
Since you seem to create a click event listener which will effect the class in html, here is the Vue way:
<template>
<header>
<div
class="button_container"
id="toggle"
:class="{
'active': isActiveBm
}"
@click="toggle">
<span class="top"></span>
<span class="middle"></span>
<span class="bottom"></span>
</div>
<div
class="overlay"
id="overlay"
:class="{
'open': isOpenOverlay
}">
<nav class="overlay-menu">
<ul>
<li><a href="#home">Home</a></li>
<!-- ... -->
</ul>
</nav>
</div>
</header>
</template>
<script setup>
import { ref } from 'vue';
const isActiveBm = ref(false);
const isOpenOverlay = ref(false);
const toggle = () => {
isActiveBm.value = !isActiveBm.value;
isOpenOverlay.value = !isOpenOverlay.value;
}
</script>
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