Search code examples
javascriptvue.jsvue-componentvuetify.js

Vuetify 3 component with weird behavior


I have a vuetify component that is based on this menu here each menu item is assigned an event listener for when the cursor enters ('mouseenter'). The problem is that the first time the page is rendered the menu items don't take the event listener but, when I update something in the code, e.g. I add and remove the prop flat to a v-btn, the problem is solved.

In that link you can find the original menu design with pure html-css-js, I've already tried that and same weird result

<template>
    <v-card>
        <v-app-bar color="bg1" style="overflow: visible;">
            <v-app-bar-nav-icon class="hidden-sm-and-up" icon="mdi-dots-vertical" variant="text" @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
            <v-toolbar-title>my menu title</v-toolbar-title>
            <v-spacer></v-spacer>
            <v-card 
            flat
            color="transparent"
            class="hidden-sm-and-down  d-sm-flex px-5 me-5 rounded-0" 
            style="height: 64px;overflow: visible;">
                <span class="list active justify-center align-center d-flex">
                    <v-btn class="icon" icon="mdi-home-outline"></v-btn>
                </span>
                <span class="list justify-center align-center d-flex">
                    <v-btn  class="icon" icon="mdi-account-circle"></v-btn>
                </span>
                <span class="list justify-center align-center d-flex">
                    <v-btn class="icon" icon="mdi-credit-card-outline"></v-btn>
                </span>
                <span class="list justify-center align-center d-flex">
                    <v-btn  class="icon" icon="mdi-image-multiple-outline"></v-btn>
                </span>
                <span class="list justify-center align-center d-flex">
                    <v-btn class="icon" icon="mdi-email-outline"></v-btn>
                </span>
                <div class="indicator"></div>
            </v-card>
        </v-app-bar>
        <v-navigation-drawer color="background" class="hidden-md-and-up" v-model="drawer" location="left">
            <!--navigation drawer, not included because it's irrelevant-->
        </v-navigation-drawer>
    </v-card>
</template>
<script>
export default {
    data: () => ({
        drawer: false,
    }),
    watch: {
        group() {
            this.drawer = false
        },
    },
}
/* segment for adding the event listener for each menu-item */
const list = document.querySelectorAll('.list');
function activeLink() {
    list.forEach((item) => item.classList.remove('active'));
    this.classList.add('active');
}
list.forEach((item) => item.addEventListener('mouseenter', activeLink));


</script>
<style scoped>
.list{
    width: 64px !important;
    background: transparent;
    z-index: 1000 !important;
    transition: 0.5s;
}
.active.list::before{
    content: '';
    position: absolute;
    bottom: 16px;
    background: #76FF03aa;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    filter: blur(5px);
}
.icon{
    color: black;
    font-size: 1.2em;
    background: #cbcec859;
}
.active.list{
    transform: translateY(32px);
    transition: 0.6s;
}
.indicator{
    width: 64px;
    height: 64px;
    background: #546E7A;
    position: absolute;
    border-radius: 50%;
    bottom: -32px;
}
.indicator::before,.indicator::after{
    content: '';
    position: absolute;
    background-color: transparent;
    border-radius: 50%;
    width: 24px;
    height: 24px;
}
.indicator::before{
    top: 32px;
    left: -22px;
    box-shadow: 9px -11px #546E7A;
}
.indicator::after{
    top: 32px;
    right: -22px;
    box-shadow: -9px -11px #546E7A;
}

.list:nth-child(2).active~.indicator {
    transform: translateX(calc(64px * 0));
    transition: 0.5s;
}
.list:nth-child(3).active~.indicator {
    transform: translateX(calc(64px * 1));
    transition: 0.5s;
}
.list:nth-child(4).active~.indicator {
    transform: translateX(calc(64px * 2));
    transition: 0.5s;
}
.list:nth-child(5).active~.indicator {
    transform: translateX(calc(64px * 3));
    transition: 0.5s;
}
.list:nth-child(6).active~.indicator {
    transform: translateX(calc(64px * 4));
    transition: 0.5s;
}
</style>

That's what I have so far. The problem is not the css that although it is extensive, even if I remove it, it doesn't intervene in the strange behaviour of the menuitems. I need to know how I can solve this problem. and where did I put the wrong finger so I don't repeat that mistake


Solution

  • As @yoduh says I should have used v-on:mouseenter="home=true" v-on:mouseleave="home=false" for the event, and :class=""{active:home} below the code snippet: Code fragment fixed