Using Bryntum Grid with Vue
Version requirements
Minimum supported:
- Vite
4.0.0or higher (for application build with Vite)
Recommended:
- Vite
5.0.0or higher (for application build with Vite)
Bryntum npm repository access
Please refer to this guide for Bryntum npm repository access.
Use Bryntum Grid with Vue
While Bryntum Grid is designed to work with any framework, it ships with demos and wrappers to simplify integration with popular frameworks like Vue.
This guide provides a basic introduction to using Bryntum Grid with Vue.
View online demos
Visit our online example browser to view demos of Bryntum Grid with Vue.
Build and run local demos
Download distribution zip with demos according to this guide.
Vue demos are located in examples/frameworks/vue and examples/frameworks/vue-3 folders inside distribution zip.
Each demo contains bundled README.md file in demo folder with build and run instructions.
To view and run an example locally in development mode, you can use the following commands:
npm install
npm run start
That starts a local server accessible at http://127.0.0.1:8080. If you modify the example code while running it locally it is automatically rebuilt and updated in the browser allowing you to see your changes immediately.
The production version of an example, or your application, is built by running:
npm install
npm run build
TypeScript and Typings
Bryntum bundles ship with typings for the classes for usage in TypeScript applications. You can find grid*.d.ts files in the build folder inside the distribution zip package. The definitions also contain a special config type which can be passed to the class constructor.
The config specific types are also accepted by multiple other properties and functions, for example the Store.data config of the Store which accepts type ModelConfig[].
Sample code for tree store creation with ModelConfig and StoreConfig classes:
import { Store, StoreConfig, ModelConfig } from '@bryntum/grid';
const storeConfig: StoreConfig = {
tree : true,
data : [
{
id : 1,
children : [
{
id : 2
}
] as ModelConfig[]
}
] as ModelConfig[]
};
new Store(storeConfig);
Wrappers
The Vue wrappers encapsulate Bryntum Grid and other Bryntum widgets in Vue components that expose configuration options, properties, features and events. The wrapped all Bryntum UI components so they can be used the usual Vue way.
To use native API package classes with wrappers import them from @bryntum/grid.
import { Grid } from '@bryntum/grid';
Installing the wrappers package
The wrappers are distributed as a separate package @bryntum/grid-vue that is installed according to the used package manager. Please refer to this guide for Bryntum npm repository access.
Wrappers Overview
Wrappers are Vue components which provide full access to Bryntum API widget class configs, properties, events and features. Each Wrapper has its own HTML tag which can be used in vue templates. This is the list of available wrappers for Bryntum Grid Vue package:
| Wrapper tag name | API widget reference |
|---|---|
| <bryntum-a-i-filter-field/> | AIFilterField |
| <bryntum-boolean-combo/> | BooleanCombo |
| <bryntum-button/> | Button |
| <bryntum-button-group/> | ButtonGroup |
| <bryntum-chat-panel/> | ChatPanel |
| <bryntum-checkbox/> | Checkbox |
| <bryntum-checkbox-group/> | CheckboxGroup |
| <bryntum-checklist-filter-combo/> | ChecklistFilterCombo |
| <bryntum-chip-view/> | ChipView |
| <bryntum-code-editor/> | CodeEditor |
| <bryntum-color-field/> | ColorField |
| <bryntum-combo/> | Combo |
| <bryntum-container/> | Container |
| <bryntum-date-field/> | DateField |
| <bryntum-date-picker/> | DatePicker |
| <bryntum-date-range-field/> | DateRangeField |
| <bryntum-date-time-field/> | DateTimeField |
| <bryntum-demo-code-editor/> | DemoCodeEditor |
| <bryntum-display-field/> | DisplayField |
| <bryntum-duration-field/> | DurationField |
| <bryntum-editor/> | Editor |
| <bryntum-field-filter-picker/> | FieldFilterPicker |
| <bryntum-field-filter-picker-group/> | FieldFilterPickerGroup |
| <bryntum-field-set/> | FieldSet |
| <bryntum-file-field/> | FileField |
| <bryntum-file-picker/> | FilePicker |
| <bryntum-filter-field/> | FilterField |
| <bryntum-grid/> | Grid |
| <bryntum-grid-base/> | GridBase |
| <bryntum-grid-chart-designer/> | GridChartDesigner |
| <bryntum-grid-field-filter-picker/> | GridFieldFilterPicker |
| <bryntum-grid-field-filter-picker-group/> | GridFieldFilterPickerGroup |
| <bryntum-group-bar/> | GroupBar |
| <bryntum-hint/> | Hint |
| <bryntum-label/> | Label |
| <bryntum-list/> | List |
| <bryntum-menu/> | Menu |
| <bryntum-month-picker/> | MonthPicker |
| <bryntum-number-field/> | NumberField |
| <bryntum-paging-toolbar/> | PagingToolbar |
| <bryntum-panel/> | Panel |
| <bryntum-password-field/> | PasswordField |
| <bryntum-progress-bar/> | ProgressBar |
| <bryntum-radio/> | Radio |
| <bryntum-radio-group/> | RadioGroup |
| <bryntum-slider/> | Slider |
| <bryntum-slide-toggle/> | SlideToggle |
| <bryntum-splitter/> | Splitter |
| <bryntum-tab-panel/> | TabPanel |
| <bryntum-text-area-field/> | TextAreaField |
| <bryntum-text-area-picker-field/> | TextAreaPickerField |
| <bryntum-text-field/> | TextField |
| <bryntum-time-field/> | TimeField |
| <bryntum-time-picker/> | TimePicker |
| <bryntum-toolbar/> | Toolbar |
| <bryntum-tree-combo/> | TreeCombo |
| <bryntum-tree-grid/> | TreeGrid |
| <bryntum-widget/> | Widget |
| <bryntum-year-picker/> | YearPicker |
Using the wrapper in your application
Now you can use the component defined in the wrapper in your application:
Sample code for App.vue:
<template>
<bryntum-grid
ref="grid"
tooltip="gridConfig.tooltip"
v-bind="gridConfig"
@click="onClick"
/>
</template>
<script>
// vue imports
import { ref, reactive } from 'vue';
// Bryntum Grid and its config
import { BryntumGrid } from '@bryntum/grid-vue-3';
import { gridConfig } from './AppConfig';
import './components/ColorColumn.js';
export default {
name: 'app',
// local components
components: {
BryntumGrid
},
setup() {
const grid = ref(null);
const config = reactive(gridConfig);
return {
grid,
gridConfig: config
};
}
};
</script>
<style lang="scss">
@import './App.scss';
</style>
As shown above you can assign values and bind to Vue data with tooltip="gridConfig.tooltip" or v-bind option. Listen to events with @click="onClick", or use v-on.
AppConfig.js should contain a simple Bryntum Grid configuration. We recommend to keep it in a separate file because it can become lengthy especially for more advanced configurations.
Sample code for AppConfig.js:
export const gridConfig = {
tooltip : "My cool Bryntum Grid component"
// Bryntum Grid config options
};
Add sass-loader to your package.json if you used SCSS.
You will also need to import CSS files for Bryntum Grid. The ideal place for doing it is the beginning of App.scss/App.css that would be imported in App.vue:
/* FontAwesome is used for icons */
@import "~@bryntum/grid/fontawesome/css/fontawesome.css";
@import "~@bryntum/grid/fontawesome/css/solid.css";
/* Structural CSS */
@import "~@bryntum/grid/grid.css";
/* Bryntum theme of your choice */
@import "~@bryntum/grid/svalbard-light.css";
Embedding widgets inside wrapper
Wrappers are designed to allow using Bryntum widgets as Vue components, but they themselves cannot contain other Bryntum wrappers inside their tag. To embed Bryntum widgets inside a wrapper you should instead use the available configuration options for the wrapper's widget. Please note that not all widgets may contain inner widgets, please refer to the API docs to check for valid configuration options.
This example shows how to use a Toolbar widget inside the wrapper for Bryntum Grid:
Sample code for AppConfig.js:
export const gridConfig = {
// Toolbar (tbar) config
tbar: {
items : {
myButton : {
type : 'button',
text : 'My button'
}
}
}
// Bryntum Grid config options
};
Syncing bound data changes
The stores used by the wrapper enable syncDataOnLoad by default (Stores not used by the wrapper have it disabled by default). It is done to make Vue column renderer update the value. Without syncDataOnLoad, each time a new array of data is set to the store would apply the data as a completely new dataset. With syncDataOnLoad, the new state is instead compared to the old, and the differences are applied.
ref to access any store (eventStore, resourceStore etc). Vue 3 wraps the passed object in a JavaScript Proxy, which can cause unexpected issues. Use it to get access to higher level component (Grid, Scheduler, and Gantt etc) and then access the store. Using Vue components to provide content
Vue components can be used to provide a content in various places of Bryntum based applications. The Vue components, which are intended to provide a content must be registered globally.
Register Vue component
This is usually implemented in main.js before the global Vue instance is created.
import { createApp } from 'vue';
import App from './App.vue';
import BlueButton from './components/BlueButton.vue';
import RedButton from './components/RedButton.vue';
import PercentBar from './components/PercentBar.vue';
const app = createApp(App);
// Register components globally to be accessible in renderers
app.component('BlueButton', BlueButton);
app.component('RedButton', RedButton);
app.component('PercentBar', PercentBar);
app.mount('#app');
// etc...
The BlueButton could look like this:
<template>
<button class="b-button b-blue" @click="click($event)">
<span>{{ htmlText }}</span>
</button>
</template>
<script>
import { computed } from 'vue';
import { StringHelper } from '@bryntum/grid';
export default {
name : 'BlueButton',
props : ['record', 'clickHandler'],
setup(props) {
const htmlText = computed(() => {
return StringHelper.encodeHtml(props.record.city);
});
const click = () => {
props.clickHandler(htmlText.value, 'b-blue');
};
return {
htmlText,
click
};
}
};
</script>
Using Vue components in cells
The wrapper implements support for using Vue Components to render the cell content. There are several steps needed to configure that in the application:
- Register Vue component globally
- Implement column renderer
- Implement methods called in Vue component
You can see the online examples here:
Implement column renderer
The column with Vue component must have a specific configuration:
{
text : 'Button',
field : 'city',
vue : true, // Required flag
renderer({ grid: { extraData : { clickHandler } }, record }) {
// The object needed by the wrapper to render the component
return {
// Required. Name of the component to render.
// The component must be registered globally in main.js
// https://vuejs.org/v2/guide/components.html#Dynamic-Components
is : 'BlueButton',
// `BlueButton` gets its text from `record`
record,
// Button click handler defined above
clickHandler
};
}
vue : true is mandatory and is property of the returned object is also required.
Implement methods called in Vue component
Should the component be interactive it needs handlers to process the user actions. The handler can be implemented locally to the component if it does not need any outside data or it can be passed to the component from an upper level. For example:
<template>
<div id="container">
<bryntum-grid
v-bind="gridConfig"
:extraData="extraData"
/>
</div>
</template>
<script>
import { reactive } from 'vue';
import { BryntumGrid } from '@bryntum/grid-vue-3';
import { Toast } from '@bryntum/grid';
import { gridConfig } from './AppConfig';
export default {
name : 'App',
components : {
BryntumGrid
},
setup() {
const clickHandler = (html, color) => {
Toast.show({ html, color, timeout : 3000 });
};
const extraData = reactive({
clickHandler
});
return {
gridConfig : reactive(gridConfig),
extraData
};
}
};
</script>
Using Vue component in widgets and tooltips
Any widget or tooltip content can be provided by a Vue component. There are several steps to implement that:
- Register Vue component globally
- Configure
htmlproperty for widgets orrendererfor tooltips
For example, to configure a cell tooltip the following code is needed:
cellTooltipFeature : {
tooltipRenderer({ record }) {
return {
vue : true, // Required flag
is : 'VueTooltip',
bind : { record }
};
}
},
The return value of the renderer must be an object minimally with vue: true and is properties. The string value of is is the component name registered in main.js.
To configure a widget the following code can be used:
const propHello = ref('Hello');
const propWorld = ref('world!');
function handleMyClick() {
// ...
}
const bbar = {
items : {
myWidget : {
type : 'widget',
html : {
vue : true, // Required flag
is : 'VueWidget', // must be registered
bind : { propHello, propWorld },
on : { myclick : handleMyClick }
}
}
}
}
bbar can then be bound to a Grid component. Properties propHello and propWorld are passed down to the VueWidget component. Any changes of these properties are then reflected in VueWidget. Custom event myclick is bound to the handler handleMyClick.
You can see the above examples in action in this demo.
Configs, properties and events
All Bryntum Vue Wrappers support the full set of the public configs, properties and events of a component.
Using dataChange event to synchronize data
Bryntum Grid keeps all data in its stores, which are automatically synchronized with the UI and the user actions. Nevertheless, it is sometimes necessary for the rest of the application to be informed about data changes. For that it is easiest to use dataChange event.
<template>
<div>
<bryntum-grid
ref="grid"
v-bind="gridConfig"
@datachange="syncData"
/>
</div>
</template>
<script>
import { BryntumGrid } from "@bryntum/grid-vue-3";
import { gridConfig } from "./AppConfig.js";
export default {
name: "App",
components: { BryntumGrid },
methods: {
syncData({ store, action, records }) {
console.log(`${store.id} changed. The action was: ${action}. Changed records: `, records);
// Your sync data logic comes here
}
},
data() {
return { gridConfig };
}
};
</script>
Wrapper configs
relayStoreEvents- set it totrueto relay events from stores toGridinstance.dataChangeevent fires twice if set to true. Defaults tofalse.
Features
Features are suffixed with Feature and act as both configs and properties for BryntumGridComponent. They are mapped to the corresponding API features of the Bryntum Grid instance.
This is a list of all BryntumGridComponent features:
| Wrapper feature parameter | API feature reference |
|---|---|
| :ai-feature | AI |
| :ai-filter-feature | AIFilter |
| :cell-copy-paste-feature | CellCopyPaste |
| :cell-edit-feature | CellEdit |
| :cell-menu-feature | CellMenu |
| :cell-tooltip-feature | CellTooltip |
| :charts-feature | Charts |
| :column-auto-width-feature | ColumnAutoWidth |
| :column-drag-toolbar-feature | ColumnDragToolbar |
| :column-picker-feature | ColumnPicker |
| :column-rename-feature | ColumnRename |
| :column-reorder-feature | ColumnReorder |
| :column-resize-feature | ColumnResize |
| :excel-exporter-feature | ExcelExporter |
| :file-drop-feature | FileDrop |
| :fill-handle-feature | FillHandle |
| :filter-feature | Filter |
| :filter-bar-feature | FilterBar |
| :group-feature | Group |
| :group-summary-feature | GroupSummary |
| :header-menu-feature | HeaderMenu |
| :lock-rows-feature | LockRows |
| :merge-cells-feature | MergeCells |
| :pdf-export-feature | PdfExport |
| :pin-columns-feature | PinColumns |
| :print-feature | |
| :quick-find-feature | QuickFind |
| :region-resize-feature | RegionResize |
| :row-copy-paste-feature | RowCopyPaste |
| :row-edit-feature | RowEdit |
| :row-expander-feature | RowExpander |
| :row-reorder-feature | RowReorder |
| :row-resize-feature | RowResize |
| :search-feature | Search |
| :sort-feature | Sort |
| :split-feature | Split |
| :sticky-cells-feature | StickyCells |
| :stripe-feature | Stripe |
| :summary-feature | Summary |
| :tree-feature | Tree |
| :tree-group-feature | TreeGroup |
Configuring features
Most features are enabled by default, in which case you can disable them like this:
const gridProps = {
// other config
cellEditFeature : false,
groupFeature : false,
};
Others require you to enable them:
const gridProps = {
// other config
sortFeature : 'name', // enabled by default but configured to be sorted by name field.
filterFeature : true,
};
To learn more about configuration, visit the feature page from the API Feature reference table above.
Bryntum Grid API instance
It is important to know that the Vue BryntumGridComponent is not the native Bryntum Grid instance, it is a wrapper or an interface between the Vue application and the Bryntum Grid itself.
All available configs, properties and features are propagated from the wrapper down to the underlying Bryntum Grid instance, but there might be the situations when you want to access the Bryntum Grid directly. That is fully valid approach and you are free to do it.
If you need to access Bryntum Grid functionality not exposed by the wrapper, you can access the Bryntum Grid instance directly. Within the Vue 2 wrapper it is available under the instance property. This simple example shows how you could use it: App.vue:
<template>
<bryntum-grid ref="grid" v-bind="gridProps" />
</template>
<script>
// Bryntum Grid and its config
import { BryntumGrid } from '@bryntum/grid-vue-3';
import { gridConfig } from './GridConfig';
import './components/ColorColumn.js';
// App
export default {
name: 'App',
// local components
components: {
BryntumGrid
},
data() {
return { gridConfig };
},
methods: {
doSomething() {
// Reference to Bryntum Grid instance
const gridInstance = this.$refs.grid.instance;
// NOTE: Do not use assignment to this.gridInstance
// Vue will wrap Bryntum Grid instance with Proxy class
// and this will not work as expected.
// Refer to this Vue guide for the details:
// https://vuejs.org/guide/extras/reactivity-in-depth.html
}
}
};
</script>
<style lang="scss">
@import './App.scss';
</style>
When accessing instance directly, use wrapper's API widget reference docs from the list above to get available configs and properties.
If you need to access Bryntum Grid functionality not exposed by the wrapper, you can access the Bryntum Grid instance directly. Within the Vue 3 wrapper it is available under the instance.value property. This simple example shows how you could use it: App.vue:
<template>
<bryntum-grid ref="grid" v-bind="gridConfig" />
</template>
<script>
// vue imports
import { ref, reactive } from 'vue';
// Bryntum Grid and its config
import { BryntumGrid } from '@bryntum/grid-vue-3';
import { useGridProps } from './GridConfig';
import './components/ColorColumn.js';
// App
export default {
name: 'App',
// local components
components: {
BryntumGrid
},
setup() {
const grid = ref(null);
const gridProps = reactive(useGridProps());
doSomething() {
// Reference to Bryntum Grid instance
const gridInstance = grid.value.instance.value;
// NOTE: Do not use assignment to this.gridInstance
// Vue will wrap Bryntum Grid instance with Proxy class
// and this will not work as expected.
// Refer to this Vue guide for the details:
// https://vuejs.org/guide/extras/reactivity-in-depth.html
}
return {
grid,
gridProps,
doSomething
};
},
};
</script>
<style lang="scss">
@import './App.scss';
</style>
When accessing instance directly, use wrapper's API widget reference docs from the list above to get available configs and properties.
Troubleshooting
Please refer to this Troubleshooting guide.
References
- Config options, features, events and methods Bryntum Grid API docs
- Visit Vue Framework Homepage
- Post your questions to Bryntum Support Forum
- Contact us