Vue Data Grid
ApexGrid is a Lit web component, so it works in Vue 3 as a custom element. This guide covers the Vite setup, property binding, imperative access, and events.
Installation
npm install apex-grid
Vite configuration
Tell Vue's template compiler to treat ApexGrid (and its sub-components) as custom elements, so it does not try to resolve them as Vue components. With Vite:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue({
template: {
compilerOptions: {
// treat all tags with a dash as custom elements
isCustomElement: (tag) => tag.includes('-'),
},
},
}),
],
})
Usage
Register the element once with the side-effect import apex-grid/define, then use <apex-grid> in your template. Use the .prop modifier so Vue binds arrays and objects as JavaScript properties rather than HTML attributes.
<script setup>
import 'apex-grid/define'
const users = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' },
]
const columns = [
{ key: 'id', headerText: 'ID', type: 'number' },
{ key: 'name', headerText: 'Name', sort: true, filter: true },
{ key: 'email', headerText: 'Email', sort: true },
]
</script>
<template>
<apex-grid :columns.prop="columns" :data.prop="users"></apex-grid>
</template>
Binding complex data
When binding complex data such as objects and arrays, use the .prop modifier so Vue sets a DOM property instead of a (stringified) attribute:
<apex-grid :columns.prop="columns" :data.prop="users"></apex-grid>
See the Vue guide on passing DOM properties for more.
Accessing the grid imperatively
Put a template ref on the element to get the underlying DOM node, then call grid methods on it after mount:
<script setup>
import { ref, onMounted } from 'vue'
import 'apex-grid/define'
import type { ApexGrid } from 'apex-grid'
const gridEl = ref<ApexGrid>()
const users = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' },
]
const columns = [
{ key: 'id', headerText: 'ID', type: 'number' },
{ key: 'name', headerText: 'Name', sort: true },
]
onMounted(() => {
const grid = gridEl.value
grid?.sort({ key: 'name', direction: 'ascending' })
})
</script>
<template>
<apex-grid ref="gridEl" :columns.prop="columns" :data.prop="users"></apex-grid>
</template>
Listening to events
ApexGrid dispatches its events as native CustomEvents. The most reliable way to handle them in Vue is to attach a listener on the element ref in onMounted, reading the payload from event.detail:
<script setup>
import { ref, onMounted } from 'vue'
import 'apex-grid/define'
import type { ApexGrid } from 'apex-grid'
const gridEl = ref<ApexGrid>()
onMounted(() => {
const grid = gridEl.value
grid?.addEventListener('rowSelected', (e) => {
console.log('selected:', (e as CustomEvent).detail)
})
grid?.addEventListener('sorted', (e) => {
console.log('sorted:', (e as CustomEvent).detail)
})
})
</script>
<template>
<apex-grid ref="gridEl" :columns.prop="columns" :data.prop="users"></apex-grid>
</template>
Template v-on binding also works in a build setup (SFC templates preserve the event-name case), for example @rowSelected="onRowSelected". The event name is case-sensitive, so match it exactly; the addEventListener approach above avoids any casing ambiguity.
Commonly used events dispatched by ApexGrid (the -ing / -Changing variants fire before the operation and are cancellable; see the React guide for the complete list):
| Event | Detail |
|---|---|
rowSelected | The selected row data |
cellValueChanged | Updated cell value and row data |
sorted | Active sort expression |
filtered | Active filter state |
pageChanged | New page index and size |