I want to create a mini profile in form of a menu by using Vuetify.js that can be called by different objects in my SPA so I thought it would be a good idea to create a component for it.
The component looks like this:
MiniProfileMenu.vue
<template>
<v-menu
v-model="menu"
:close-on-content-click="false"
location="end"
>
<template v-slot:activator="{ activator }">
<slot v-bind="activator"/>
</template>
<v-card>
<v-row>
<v-col cols="auto" style="width: 64px">
Avatar
</v-col>
<v-col>
<h4>User</h4>
<p class="text-grey-darken-1">User Desc</p>
</v-col>
</v-row>
</v-card>
</v-menu>
</template>
<script>
export default {
name: "MiniProfileMenu",
data() {
return {
menu: false,
activator: null,
};
},
methods: {
open(user, activator) {
this.activator = activator;
this.menu = true;
},
close() {
this.menu = false;
},
},
}
</script>
<style scoped>
.profile-card {
width: 100%;
}
</style>
And this is the case I would like to use it:
DashboardCommunityPage.vue
<template>
<v-container>
<v-row>
<v-spacer />
<v-col cols="auto">
<mini-profile-menu ref="miniProfile">
<div
@click="openMiniProfile(user_uuid)"
>
Click me!
</div>
</mini-profile-menu>
</v-col>
<v-spacer />
</v-row>
</v-container>
</template>
<script>
import MiniProfileMenu from "#/components/MiniProfileMenu.vue";
export default {
name: "DashboardCommunityPage",
components: {MiniProfileMenu},
methods: {
openMiniProfile(uuid) {
this.$refs.miniProfile(uuid);
}
}
};
</script>
My problem is now, that I get the error
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'key')
from the v-bind
on the <slot />
in my MiniProfileMenu component. I would like to bind it to the div that is in the slot of the MiniProfileMenu so the menu appears next to it on click. Is it possible to do that in another way?
Thanks in advance
In the Vuetify menu
component there is no props called activator
.
Instead you need to bind the props
prop to where you want the menu to open on click.
And in your menu component you can expose this props to the parent component by binding this to the slot
.
<!-- my-menu.vue -->
<template>
<v-menu>
<template v-slot:activator="{ props }">
<slot v-bind="props" />
</template>
<v-card>
<!-- Content showed when opened -->
</v-card>
</v-menu>
</template>
<!-- parent component -->
<template>
<MyMenu v-slot="props"> <!-- We can access the props exposed from the child component -->
<v-btn v-bind="props">
Click me!
</v-btn>
</MyMenu>
</template>