我正在尝试向 DataTable 中的行添加链接/按钮,单击后会将您带到 vue 路线。当然,我可以简单地添加一个普通的 <a>
链接,其中包含 href="/item/${id}"
。但这会绕过路由器并导致整个页面重新加载
我想出了两个解决方案,这两个解决方案都依赖于设置 onclick
来执行一些代码:
在route1
中,我将一个名为vueRoute
的函数附加到window
对象,该函数只是对vue方法route1
的引用。现在可以从任何地方调用此函数
在 route2
中,我让 onclick
触发 CustomEvent
,并且我设置了一个事件侦听器以由 route2
vue 方法处理它
我对这两种解决方案都不满意。尽管它们有效,但它们看起来很“hacky”。我应该做什么?
// 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); },
可以在此处找到工作示例:https://stackblitz.com/edit/datatables-net-vue3-simple-mgdhf1?file=src/components/ListView.vue
编辑:我实际上最终做的是切换到无头表组件(TanStack),它在 Vue 中运行得比 DataTables 更好。但如果您需要使用 DataTables,@Damzaky 和 @Moritz Ringler 下面发布的解决方案可以正常工作
我不会说这是最好的解决方案,但在我看来,据我所知,没有真正的“最佳”解决方案,因为数据表使用 jQuery 而你在这里使用 vue (DOM 控件很友好)的不一致)。经过快速搜索,我没有找到办法 在数据表的
render
属性内渲染一个 vue 组件。所以我的想法不同,它简化渲染函数,并使用
drawCallback
添加事件侦听器,并使用事件委托来附加侦听器。来自文档:
因此,我只需将
data-item-id
附加到每个链接,然后使用父级的单击事件来执行路由器推送(事件委托)。我知道这不是最好的答案,但也许这可能是您的另一种选择。这个如果您感兴趣的话,这是分叉的沙箱。
您可以在 DataTable 对象上设置
@click
处理程序:该事件将是常规点击事件,因此我们需要一个可识别的 id 数据集属性:
点击处理程序只需确保可以检索 id,确保点击来自链接:
这里是更新后的 堆栈闪电战
有趣的是,正如背景一样,问题甚至不是 Vue 和 jQuery 之间的连接,而是 DataTables 的工作方式,特别是没有单击单元格或单击行的事件,并且渲染器只能返回 HTML 字符串。
这并不奇怪,这就是 jQuery 的工作原理,其中数据、视图和行为并不是内在链接的,但您可以按照自己认为合适的方式将它们连接起来。因此,我们没有可以利用的单元格单击事件,因为在 jQuery 中,您自己编写它,否则它就不存在。
在 jQuery 中设置处理程序的最有效方法是使用目标过滤器在表上设置事件:
优点是:
上面的 Vue 解决方案做了完全相同的事情,只是没有 jQuery。
所以我认为这是使其在 Vue 中工作的最有效方法,无论是在代码量(可维护性)还是性能方面。
请注意,由于 DataTable 要求 jQuery 可以全局访问,因此它也可以在您的 Vue 组件中使用,并且您可以将给定的 jQuery 语句放入
mounted
挂钩中,您可以在其中访问 Vue 路由器在回调中。因此,您不必将路由器置于全局范围内以便在 jQuery 端使用它,而是可以使用 Vue 端已有的对象。尽管如此,由于没有必要将 jQuery 混合到您的 Vue 代码中,所以我会避免它并使用上面的仅 Vue 解决方案。