Properties of the Object Type
Use nested configuration components. In the following example, we configure the Chart's tooltip property:
<template> <DxChart> <DxTooltip :enabled="true" format="thousands" /> </DxChart> </template> <script> import DxChart, { DxTooltip } from 'devextreme-vue/chart'; export default { components: { DxChart, DxTooltip } } </script>
Object type properties that depend on other properties' values are not implemented as nested configuration components because they cannot be typed (columns[].editorOptions in the DataGrid, item's editorOptions in the Form, items[].options in the Toolbar). These properties should be specified with an object.
<template> <DxDataGrid> <DxColumn :editor-options="columnEditorOptions" /> </DxDataGrid> </template> <script> import DxDataGrid, { DxColumn } from 'devextreme-vue/data-grid'; export default { components: { DxDataGrid, DxColumn }, data() { return { columnEditorOptions: { width: 100 } } } } </script>
Collections
Use nested configuration components. The following example shows how to configure the DataGrid's columns property:
<template> <DxDataGrid> <DxColumn data-field="firstName" caption="Name" /> <DxColumn data-field="lastName" caption="Surname" /> </DxDataGrid> </template> <script> import DxDataGrid, { DxColumn } from 'devextreme-vue/data-grid'; export default { components: { DxDataGrid, DxColumn } } </script>
DevExtreme collection UI components also support the DxItem
element. It allows you to declare collection items in the UI component markup. DxItem
can contain custom markup and have attributes that control parts of item appearance, such as badge
in the following code. The attributes are described in the items section of each collection UI component. Ensure to specify that an item's content is in the default slot.
<template> <DxList> <DxItem #default>Orange</DxItem> <DxItem #default badge="New">White</DxItem> <DxItem #default>Black</DxItem> </DxList> </template> <script> import DxList, { DxItem } from 'devextreme-vue/list'; export default { components: { DxList, DxItem } } </script>
DxItem
also supports structural directives provided by Vue, such as v-for
:
<template> <DxList> <DxItem #default><h1>Available items</h1></DxItem> <DxItem v-for="item in listItems" :key="item.text" :badge="item.badge" #default> {{ item.text }} </DxItem> </DxList> </template> <script> import DxList, { DxItem } from 'devextreme-vue/list'; export default { components: { DxList, DxItem }, data() { return { listItems: [{ text: 'Cars', badge: '12' }, { text: 'Bikes', badge: '5' }] } } } </script>
Event Handling
<template> <DxButton text="OK" @click="okClicked" /> </template> <script> import DxButton from 'devextreme-vue/button'; import notify from 'devextreme/ui/notify'; export default { components: { DxButton }, methods: { okClicked: function(e) { notify('The OK button was clicked') } } } </script>
One-Way Property Binding
Changes in the bindingProperty
are propagated to the TextBox's value, but not vice versa. :
before value is a shorthand for the v-bind
directive.
<template> <DxTextBox :value="bindingProperty" /> </template> <script> import DxTextBox from 'devextreme-vue/text-box'; export default { components: { DxTextBox }, data() { return { bindingProperty: 'Some value' } } } </script>
Two-Way Property Binding
Changes in the bindingProperty
are propagated to the TextBox's value and vice versa. The sync
modifier provides two-way binding.
<template> <DxTextBox :value.sync="bindingProperty" /> </template> <script> import DxTextBox from 'devextreme-vue/text-box'; export default { components: { DxTextBox }, data() { return { bindingProperty: 'Some value' } } } </script>
Declare Content in the Markup
The following UI components allow you to declare their content directly in the markup:
- Drawer
- DropDownBox
- HtmlEditor
- Popover
- Popup
- Resizable
- ScrollView
- SlideOutView
- Tooltip
- ValidationGroup
The following is an example with ScrollView:
<template> <DxScrollView> <div>Some scrollable content</div> </DxScrollView> </template> <script> import DxScrollView from 'devextreme-vue/scroll-view'; export default { components: { DxScrollView } } </script>
These UI components do not support dynamically or conditionally rendered content in their root element. For example, the following code does not work:
<template> <DxDrawer ... > <router-view></router-view> </DxDrawer> </template>
Wrap the content in a static element:
<template> <DxDrawer ... > <div> <router-view></router-view> </div> </DxDrawer> </template>
Templates
Templates allow you to customize UI components. DevExtreme templates make use of the named slots functionality provided by Vue.
In the following code, an itemTemplate called list-item
and a groupTemplate called list-group
customize items and groups in the List UI component. The data
slot prop exposes the item or group data object; the index
slot prop gives access to the item index.
<template> <DxList :items="groupedItems" :grouped="true" item-template="list-item" group-template="list-group"> <template #list-item="{ data, index }"> {{ index }} - {{ data.itemProperty }} </template> <template #list-group="{ data }"> {{ data.groupProperty }} </template> </DxList> </template> <script> import DxList from 'devextreme-vue/list'; export default { components: { DxList }, data() { return { groupedItems: [ /* ... */ ] } } } </script>
<template>
should not contain more than one root element.Refer to the common Custom Templates article for more information.
Call Methods
To call UI component methods, you need the UI component instance. Define its key in the ref
attribute. Then, pass the key to the $refs
property to get the component. The UI component instance is stored in the component's instance
field:
<template> <div> <DxTextBox :ref="textBoxRefKey" /> <DxButton text="Focus TextBox" @click="focusTextBox" /> </div> </template> <script> import DxButton from 'devextreme-vue/button'; import DxTextBox from 'devextreme-vue/text-box'; const textBoxRefKey = "my-text-box"; export default { components: { DxTextBox, DxButton }, data: function() { return { textBoxRefKey }; }, methods: { focusTextBox: function() { this.textBox.focus(); } }, computed: { textBox: function() { return this.$refs[textBoxRefKey].instance; } } }; </script>
Alternatively, you can assign the UI component instance to a variable and use it to call the methods:
<template> <div> <DxDataGrid ... @initialized="saveGridInstance"> </DxDataGrid> <DxButton text="Refresh data" @click="refresh"/> </div> </template> <script> import DxDataGrid from 'devextreme-vue/data-grid'; import DxButton from 'devextreme-vue/button'; export default { components: { DxDataGrid, DxButton }, data: function() { return { dataGridInstance: null }; }, methods: { saveGridInstance: function(e) { this.dataGridInstance = e.component; }, refresh: function() { this.dataGridInstance.refresh(); } } }; </script>
Data Layer
DevExtreme Data Layer is a set of components for working with data. Refer to the Data Layer API reference for code examples.
DevExtreme Validation Features
In the following example, two textboxes are placed in a validation group that is validated on a button click. Each textbox has a set of validation rules. The validation result is displayed under the textboxes in a validation summary.
<template> <DxValidationGroup> <DxTextBox :value.sync="email"> <DxValidator> <DxRequiredRule message="Email is required" /> <DxEmailRule message="Email is invalid" /> </DxValidator> </DxTextBox> <DxTextBox :value.sync="password" mode="password"> <DxValidator> <DxRequiredRule message="Password is required" /> </DxValidator> </DxTextBox> <DxValidationSummary /> <DxButton @click="validate" text="Submit" /> </DxValidationGroup> </template> <script> import DxTextBox from 'devextreme-vue/text-box'; import DxValidator, { DxRequiredRule, DxEmailRule } from 'devextreme-vue/validator'; import DxValidationGroup from 'devextreme-vue/validation-group'; import DxValidationSummary from 'devextreme-vue/validation-summary'; import DxButton from 'devextreme-vue/button'; export default { components: { DxTextBox, DxValidator, DxRequiredRule, DxEmailRule, DxValidationGroup, DxValidationSummary, DxButton }, data() { return { email: undefined, password: undefined } }, methods: { validate(params) { let result = params.validationGroup.validate(); if (result.isValid) { // the values are valid // submit and reset them // params.validationGroup.reset(); console.log(result); } } } } </script>
Refer to the Data Validation article for more information.
Vue Form Input Bindings Support
DevExtreme editors support the v-model
directive that creates two-way binding on the editor's value.
<template> <DxTextBox v-model="bindingProperty" /> </template> <script> import DxTextBox from 'devextreme-vue/text-box'; export default { components: { DxTextBox }, data() { return { bindingProperty: 'Some value' } } } </script>
Alternatively, you can use the sync
modifier.
If you have technical questions, please create a support ticket in the DevExpress Support Center.