npm create vite ag-grid-project -- --template vue-ts
cd ag-grid-project
npm install
npm run dev
npm install vuestic-ui @vuestic/ag-grid-theme sass
import { createApp } from "vue";
import App from "./App.vue";
import { createVuesticEssential } from "vuestic-ui"; // <--
import 'vuestic-ui/dist/vuestic-ui.css' // <--
const app = createApp(App);
app.use(createVuesticEssential()); // <--
app.mount("#app");
<template>
<div style="height: 300px; width: 100%;">
<ag-grid-vue
class="ag-theme-vuestic"
style="width: 100%; height: 100%;"
:columnDefs="columnDefs"
:rowData="reactiveUsers"
:modules="modules"
/>
</div>
</template>
<script setup lang="ts">
import { AgGridVue } from '@ag-grid-community/vue3'
import {
ClientSideRowModelModule,
} from '@ag-grid-community/client-side-row-model'
import { users } from '../data/users'
import { reactive } from 'vue'
const modules = [ClientSideRowModelModule]
const reactiveUsers = reactive(users)
const columnDefs = [
{ field: 'name' },
{ field: 'email' },
]
</script>
<style lang="scss">
@import "@vuestic/ag-grid-theme/index.scss";
</style>
type User = {
id: number,
image: string,
name: string,
email: string,
active: boolean,
}
export const users: User[] = [
{
id: 1,
image: 'https://picsum.photos/id/1/50/50',
name: 'Ashley Mcdaniel',
email: 'ashleymcdaniel@nebulean.com',
active: true,
},
...
<template>
<va-avatar :src="url" :size="44" />
</template>
<script setup lang="ts">
import { VaAvatar } from 'vuestic-ui'
import { computed } from 'vue'
const props = defineProps<{params: {value: string}}>()
const url = computed(() => props.params.value)
</script>
const columnDefs = [
{ field: 'image', cellRenderer: UserImage, width: 65 },
...
<template>
<va-switch class="user-active" v-model="user.active" size="small" />
</template>
<script setup lang="ts">
import { VaSwitch } from 'vuestic-ui'
import { computed, reactive } from 'vue'
import { User } from '../data/users'
const props = defineProps<{params: {data: User}}>()
// AG Grid strips reactivity for some reason, so we have to force it back.
const user = computed(() => reactive(props.params.data))
</script>
const columnDefs = [
...
{ field: 'active', cellRenderer: UserActive, width: 75 },
const active = computed(() => props.params.data.active)
const setActive = (value) => api.setActive(props.params.data.id, value)
<va-switch :modelValue="active" @modelValue:update="setActive" />
const columnDefs = [
{ field: 'image', headerName: '', cellRenderer: UserImage, width: 65 },
{ field: 'name', sortable: true },
{ field: 'email', sortable: true },
{ field: 'active', cellRenderer: UserActive, width: 75, sortable: true },
]
<template>
<va-input
v-model="filter"
placeholder="Filter..."
/>
<div style="height: 300px; width: 100%;">
<ag-grid-vue
class="ag-theme-vuestic"
style="width: 100%; height: 100%;"
:columnDefs="columnDefs"
:rowData="reactiveUsers"
:isExternalFilterPresent="() => true"
:doesExternalFilterPass="doesExternalFilterPass"
@grid-ready="onGridReady"
:modules="modules"
/>
</div>
</template>
<script setup lang="ts">
...
const filter = ref('')
let gridApi: any = null
const onGridReady = (params: any) => {
gridApi = params.api
}
watch(() => filter.value, () => {
gridApi.onFilterChanged()
})
const doesExternalFilterPass = ({ data: user }: {user: User}) => {
return JSON.stringify(user).includes(filter.value)
}
...
<template>
<div>
<va-button flat icon="edit" @click="editUser(user)" />
<va-button flat icon="close" @click="removeUser(user)" />
</div>
</template>
<script setup lang="ts">
import { VaButton } from 'vuestic-ui'
import { computed, reactive } from 'vue'
import { User } from '../data/users'
const props = defineProps<{params: {data: User, context: {
editUser: (user: User) => {},
removeUser: (user: User) => {},
}}}>()
const { editUser, removeUser } = props.params.context
const user = computed(() => reactive(props.params.data))
</script>
<va-button @click="createUser()" icon="add" text-color="white" color="success" />
<va-modal
:model-value="!!selectedUser"
ok-text="Save"
cancel-text="Cancel"
@cancel="selectedUser = null"
@ok="saveUser()"
>
<va-input class="mb-3 d-block" label="Image" v-model="selectedUser.image"/>
<va-input class="mb-3 d-block" label="Name" v-model="selectedUser.name"/>
<va-input class="mb-3 d-block" label="Email" v-model="selectedUser.email"/>
</va-modal>
const editUser = (user: User) => {
selectedUser.value = { ...user }
}
const removeUser = (userToRemove: User) => {
reactiveUsers.value = reactiveUsers.value.filter(user => user !== userToRemove)
}
const createUser = () => {
selectedUser.value = {
id: Math.ceil(Math.random()*10000),
image: 'https://picsum.photos/id/100/50/50',
name: '',
email: '',
active: true,
}
}
const saveUser = () => {
const currentUser = selectedUser.value
selectedUser.value = null
if (!currentUser) {
return
}
const users = reactiveUsers.value
const existingUser = users.find(user => user.id === currentUser.id)
if (existingUser) {
reactiveUsers.value = reactiveUsers.value.map(user => existingUser === user ? currentUser : user)
} else {
reactiveUsers.value.push(currentUser)
}
}
const agGridContext = {
editUser,
removeUser,
}
<ag-grid-vue
...
:context="agGridContext"
/>