我正在嘗試在 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 下面發布的解決方案可以正常工作
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 解決方案。