Heim > Fragen und Antworten > Hauptteil
Ich versuche, einer Zeile in einer DataTable einen Link/eine Schaltfläche hinzuzufügen, der Sie beim Klicken zu einer Vue-Route führt. Natürlich könnte ich auch einfach ein schlichtes <a>
链接,其中包含 href="/item/${id}"
hinzufügen. Dies umgeht jedoch den Router und führt dazu, dass die gesamte Seite neu geladen wird
Ich habe zwei Lösungen gefunden, die beide auf der Einstellung onclick
basieren, um Code auszuführen:
Zitate in route1
中,我将一个名为vueRoute
的函数附加到window
对象,该函数只是对vue方法route1
. Diese Funktion kann nun von überall aufgerufen werden
In route2
habe ich route2
中,我让 onclick
触发 CustomEvent
,并且我设置了一个事件侦听器以由 route2
den Auslöser CustomEvent
und einen Ereignis-Listener eingerichtet, um ihn mit der Vue-Methode route2
zu verarbeiten
Ich bin mit keiner Lösung zufrieden. Obwohl sie funktionieren, sehen sie „hackig“ aus. was soll ich machen?
// 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); },
Ein funktionierendes Beispiel finden Sie hier: https://stackblitz.com/edit/datatables-net-vue3-simple-mgdhf1?file=src/components/ListView.vue
EDIT: Am Ende habe ich tatsächlich auf eine Headless-Tabellenkomponente (TanStack) umgestellt, die in Vue besser funktioniert als DataTables. Wenn Sie jedoch DataTables verwenden müssen, funktioniert die unten von @Damzaky und @Moritz Ringler veröffentlichte Lösung einwandfrei
P粉5881526362024-03-28 17:27:38
我不会说这是最好的解决方案,但在我看来,据我所知,没有真正的“最佳”解决方案,因为数据表使用 jQuery 而你在这里使用 vue (DOM 控件很友好)的不一致)。经过快速搜索,我没有找到办法
在数据表的 render
属性内渲染一个 vue 组件。
所以我的想法不同,它简化渲染函数,并使用drawCallback
添加事件侦听器,并使用事件委托来附加侦听器。
来自文档:
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); } }); }, }, ... ......
因此,我只需将 data-item-id
附加到每个链接,然后使用父级的单击事件来执行路由器推送(事件委托)。我知道这不是最好的答案,但也许这可能是您的另一种选择。
这个如果您感兴趣的话,这是分叉的沙箱。
P粉1342887942024-03-28 16:25:12
您可以在 DataTable 对象上设置 @click
处理程序:
该事件将是常规点击事件,因此我们需要一个可识别的 id 数据集属性:
{ data: 'id', render: function (idValue) { return `route3`; }, },
点击处理程序只需确保可以检索 id,确保点击来自链接:
resolveRouteFromClick(e){ const itemId = e.target.dataset.itemId if (!itemId) { return } e.preventDefault() this.router.push('/item/' + itemId); }
这里是更新后的 堆栈闪电战
有趣的是,正如背景一样,问题甚至不是 Vue 和 jQuery 之间的连接,而是 DataTables 的工作方式,特别是没有单击单元格或单击行的事件,并且渲染器只能返回 HTML 字符串。
这并不奇怪,这就是 jQuery 的工作原理,其中数据、视图和行为并不是内在链接的,但您可以按照自己认为合适的方式将它们连接起来。因此,我们没有可以利用的单元格单击事件,因为在 jQuery 中,您自己编写它,否则它就不存在。
在 jQuery 中设置处理程序的最有效方法是使用目标过滤器在表上设置事件:
$('.datatable').on('click', 'a[data-item-id]', function(){...})
优点是:
上面的 Vue 解决方案做了完全相同的事情,只是没有 jQuery。
所以我认为这是使其在 Vue 中工作的最有效方法,无论是在代码量(可维护性)还是性能方面。
请注意,由于 DataTable 要求 jQuery 可以全局访问,因此它也可以在您的 Vue 组件中使用,并且您可以将给定的 jQuery 语句放入 mounted
挂钩中,您可以在其中访问 Vue 路由器在回调中。因此,您不必将路由器置于全局范围内以便在 jQuery 端使用它,而是可以使用 Vue 端已有的对象。
尽管如此,由于没有必要将 jQuery 混合到您的 Vue 代码中,所以我会避免它并使用上面的仅 Vue 解决方案。