primevue
primevue copied to clipboard
Menubar doesn't open the sub-menus when item is not a Proxy object
In this line: https://github.com/primefaces/primevue/blob/b917e116729d0f2d44fa452d6594f0c1cee67df0/src/components/menubar/MenubarSub.vue#L242 When we call the component Menubar with an array as model, the sub-menu doesn't open. It's due to the fact we compare a proxy element with an object.
Unable to replicate with the latest PrimeVue 3.4.1 please create a new ticket with our codesandbox template fork so that we can work on it again. Thank you.
Same issue here using PrimeVue 3.6.0.
It happens on all the menus... TieredMenu, Menubar...
The line pointed by @alexandreDavid is causing it. At the objects comparision with ===
, the activeItem is a Proxy object and the item is not.
I was able to get it work just changing the code to:
getItemClass(item) {
return [
'p-menuitem', item.class, {
'p-menuitem-active': this.activeItem.label === item.label
}
]
},
Using the label for this is not the solution, I know that, I made this just to see if it would work, and it did.
What I didn't understand looking at the code is how this item become a Proxy object...
I've followed the PrimeVue docs examples, without any customization on it. I'm using vue 3.1.5, and testing on storybook 6.3.6. The other components that I've tested work fine.
@alexandreDavid was you able to do any workaround?
I was able to work declaring my array as a reactive object.
import { reactive } from 'vue'
let items = reactive([...])
thaks for sharing @williamweckl
Aha, this helped me solve my problem. My sub-menu was not opening in Vue 3, but the menu items were just passed in tersely:
I'll just show my entire component. This wasn't working:
<script setup>
import { ref } from 'vue';
import ContextMenu from 'primevue/contextmenu';
defineProps({
employee: {
type: Object,
required: true,
},
});
const menu = ref();
const toggleMenu = (event) => {
menu.value.toggle(event);
};
</script>
<template>
<button @click="toggleMenu">
<i class="icon-more-h text-primary"></i>
</button>
<ContextMenu
ref="menu"
:model="[
{
label: 'View details',
icon: 'icon-info',
to: { name: 'dashboard.index' },
},
{
label: 'Reset password',
icon: 'icon-logout',
items: [
{
label: 'Send SMS',
},
{
label: 'Send Email',
},
],
}
]"
popup
/>
</template>
But then I changed it to this, and it now works:
<script setup>
import { ref, reactive } from 'vue';
import ContextMenu from 'primevue/contextmenu';
defineProps({
employee: {
type: Object,
required: true,
},
});
const menu = ref();
const menuItems = reactive([
{
label: 'View details',
icon: 'icon-info',
to: { name: 'dashboard.index' },
},
{
label: 'Reset password',
icon: 'icon-logout',
items: [
{
label: 'Send SMS',
},
{
label: 'Send Email',
},
],
}
]);
const toggleMenu = (event) => {
menu.value.toggle(event);
};
</script>
<template>
<button @click="toggleMenu">
<i class="icon-more-h text-primary"></i>
</button>
<ContextMenu
ref="menu"
:model="menuItems"
popup
/>
</template>
I'm guessing the problem is related to what is described by @williamweckl. When menu items is a proxy, it works.
I'll just drop a few keywords in here to help future searchers:
- primevue context menu not opening
- sub menu not working
- sub-items, subitems, submenu
Can this documented explicitly on the MenuBar Page? Currently it does not explicitly mention the required reactivity of the Menu Model, at least on the MenuBar Page. The examples use a reactive model though, so it is kinda implicit.
Especially when creating a Component with SFC Setup, like in the previous comment, one may use a non-reactive model at first.