Maison > Questions et réponses > le corps du texte
J'essaie d'ajouter un lien/bouton à une ligne d'un DataTable qui, une fois cliqué, vous amènera à un itinéraire de vue. Bien sûr, je pourrais simplement ajouter un simple <a>
链接,其中包含 href="/item/${id}"
. Mais cela contourne le routeur et provoque le rechargement de la page entière
J'ai proposé deux solutions, qui reposent toutes deux sur la configuration onclick
pour exécuter du code :
Citations en route1
中,我将一个名为vueRoute
的函数附加到window
对象,该函数只是对vue方法route1
. Cette fonction peut désormais être appelée de n'importe où
Dans route2
, j'ai route2
中,我让 onclick
触发 CustomEvent
,并且我设置了一个事件侦听器以由 route2
le déclencheur CustomEvent
et j'ai configuré un écouteur d'événement pour le gérer par la méthode vue route2
Je ne suis satisfait d’aucune des deux solutions. Bien qu'ils fonctionnent, ils ont l'air "hacky". Que dois-je faire?
// datatables column definitions columns: [ // route1 { data: 'id', render: function (dt) { return `<a href="#" onclick="(function(){vueRoute('${dt}');})()">route1</a>`; }, }, // route2 { data: 'id', render: function (dt) { return `<a href="#" onclick="(function(){document.body.dispatchEvent( new CustomEvent('clickedEdit', {detail : ${dt} }));})() ">route2</a>`; }, }, ], // vue methods methods: { route1(id) { this.router.push('/item/' + id); }, route2(evt) { this.router.push('/item/' + evt.detail); }, }, // on mount, set up route1 and route2 mounted() { window.vueRoute = this.route1; document.body.addEventListener('clickedEdit', this.route2); },
Un exemple fonctionnel peut être trouvé ici : https://stackblitz.com/edit/datatables-net-vue3-simple-mgdhf1?file=src/components/ListView.vue
EDIT : Ce que j'ai finalement fait, c'est de passer à un composant de table sans tête (TanStack), qui fonctionne mieux dans Vue que DataTables. Mais si vous devez utiliser DataTables, la solution publiée ci-dessous par @Damzaky et @Moritz Ringler fonctionnera très bien
P粉5881526362024-03-28 17:27:38
Je ne dirais pas que c'est la meilleure solution, mais à mon avis, pour autant que je sache, il n'y a pas de véritable "meilleure" solution, puisque le datatable utilise jQuery et que vous utilisez vue ici (incohérence compatible avec le contrôle DOM) . Après une recherche rapide, je n'ai pas trouvé de moyen
Affichez un composant vue dans l'attribut render
de la table de données.
Donc mon idée est différente, elle simplifie la fonction de rendu et utilise drawCallback
pour ajouter des auditeurs d'événement et utiliser des délégués d'événement pour attacher les auditeurs.
De Documents :
data() { return { ... columns: [ ... { data: 'id', render: function (dt) { return `route3`; }, }, ], }; }, methods: { ... drawCallback(settings) { const tableElm = document.getElementById(settings.sInstance); tableElm.addEventListener('click', (e) => { const id = e.target.dataset.itemId; if (id) { this.router.push('/item/' + id); } }); }, }, ... ......
Donc, j'ajoute simplement data-item-id
à chaque lien, puis j'utilise l'événement de clic du parent pour effectuer le push du routeur (délégation d'événement). Je sais que ce n'est pas la meilleure réponse, mais cela pourrait peut-être être une autre option pour vous.
C'est le bac à sable fourchu si vous êtes intéressé.
P粉1342887942024-03-28 16:25:12
Vous pouvez définir un gestionnaire @click
sur un objet DataTable :
L'événement sera un événement de clic régulier, nous avons donc besoin d'un attribut d'ensemble de données d'identification identifiable :
{ data: 'id', render: function (idValue) { return `route3`; }, },
Le gestionnaire de clics doit simplement s'assurer que l'identifiant peut être récupéré, en s'assurant que le clic provient d'un lien :
resolveRouteFromClick(e){ const itemId = e.target.dataset.itemId if (!itemId) { return } e.preventDefault() this.router.push('/item/' + itemId); }
Voici le Stack Blitz
mis à jourFait intéressant, tout comme le contexte, le problème n'est même pas la connexion entre Vue et jQuery, mais le fonctionnement des DataTables, en particulier, il n'y a pas d'événements pour le clic sur une cellule ou sur une ligne, et le moteur de rendu ne peut renvoyer que des chaînes HTML.
Ce n'est pas une surprise, c'est ainsi que fonctionne jQuery, où les données, les vues et les comportements ne sont pas intrinsèquement liés, mais vous pouvez les connecter comme bon vous semble. Nous n'avons donc pas d'événement de clic de cellule à exploiter car dans jQuery vous l'écrivez vous-même ou il n'existe pas.
Le moyen le plus efficace de définir des gestionnaires dans jQuery est de définir l'événement sur une table à l'aide d'un filtre cible :
$('.datatable').on('click', 'a[data-item-id]', function(){...})
Les avantages sont :
La solution Vue ci-dessus fait exactement la même chose, juste sans jQuery.
Je pense donc que c'est le moyen le plus efficace de le faire fonctionner dans Vue, à la fois en termes de taille de code (maintenabilité) et de performances.
Notez que puisque DataTable nécessite que jQuery soit accessible globalement, il peut également être utilisé dans votre composant Vue, et vous pouvez placer l'instruction jQuery donnée dans un hook mounted
où vous pouvez accéder au Routeur Vue dans le rappel. Ainsi, au lieu de mettre le routeur dans une portée globale pour l'utiliser côté jQuery, vous pouvez utiliser un objet qui existe déjà côté Vue.
Pourtant, comme il n'est pas nécessaire de mélanger jQuery dans votre code Vue, je l'éviterais et utiliserais la solution Vue uniquement ci-dessus.