PrimeVue, Inertia et Ziggy : un lien pour naviguer

Si comme moi vous avez décider de mélanger des trucs et que la documentation vous manque dans ce cas particulier : bienvenue !

Ici la problématique est que le système de menu de Prime utilise un router-link, mais que nous, avec Inertia et Ziggy, on doit passer par Link. Du coup comment dire à PrimeVue de changer ?

C’est sur un forum perdu quelque part que j’ai trouvé la solution, ou du moins le bon point de départ. Il s’agit de définir un composant router-link personalisé qui utilise Link. En modifiant mon fichier app.js de mon projet Goo (voir l’article de mise en place) cela donne :

createInertiaApp({
    resolve: async (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
    setup({ el, App, props, plugin }) {
        createApp({ render: () => h(App, props) })
            .use(plugin)
            .use(ZiggyVue, Ziggy)
            .use(PrimeVue)
            .component("Link", Link)
            .component("Head", Head)
            .component("router-link", {
                props: ["to","custom"],
                template: `<Link :href="to"><slot/></Link>`,
            })
            .mixin({ methods: { route } })
            .mount(el);
    },
});

À ce stade nous n’avons pas encore utilisé route de Ziggy. D’ailleur si vous encapsulé le to dans un route(to), cela ne fonctionnera pas (le Menubar refuse même de s’afficher sans erreur :/). Du coup on déplace la transformation dans la définition du menu.

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import Menubar from 'primevue/menubar'

const menuItems = ref([
        {
            label: 'Factures',
            icon: 'pi pi-fw pi-file',
            to: route('invoices')
        }
    ])
</script>

Et du coup nous voilà avec un menu PrimeVue qui fonctionne selon notre besoin Inertia et route Laravel.