Templates in Syncfusion Vue Components
28 Jun 202424 minutes to read
Syncfusion Vue components are rendered with a pre-defined layout or structure that is used to define how the component should be rendered on the user interface. The user wants to customise the appearance of the component and add functionality that is specific to the needs of the application. Syncfusion Vue components have the option to achieve this using template support.
Types of templates
Syncfusion Vue components have three types of templates, such as:
Slot template
The Syncfusion Vue components do support slots, which can help reduce the number of properties that need to be defined and increase the readability of the component. This is because using slots allows defining the content or behaviour of the component in the parent component rather than in the component’s own code. This can make it easier to understand the purpose and functionality of the component at a glance and make the component more modular and flexible.
In the Vue component, the v-slot
directive is used to define a slot template in the component’s template where users can insert custom content. Refer to the following code sample.
<ejs-grid ref="grid" :dataSource="ds">
<e-columns>
<e-column field="OrderID" headerText="Order ID" width=120 textAlign="Right" />
<e-column field="CustomerName" headerText="Customer Name" width=150 />
<e-column field="ShipCountry" headerText="Ship Country" width=150 :template="'cTemplate'">
<template v-slot:cTemplate>
<ejs-button :content="ShipCountry"></ejs-button>
</template>
</e-column>
</e-columns>
</ejs-grid>
Render scope
In a single-page application, there may be a need to access the parent component scope in the template. The slot content has access to the data scope of the parent component. To access the component’s data source value inside the template, pass the props ({data}) to the v-slot
directive. Expressions within the slot can access the component’s data source.
<template v-slot:templateName="{data}">
<ejs-button :content="data.ShipCountry"></ejs-button>
</template>
Named slot
The Syncfusion Vue components support multiple templates. Each template is differentiated by its name. To render the slot content to the corresponding slot outlet, the name of each slot must map to the name of the corresponding property.
<template v-slot:templateName></template>
When passing a slot to a component, ensure that the component’s property value is of the “string” type.
An example of a Grid component sample with a named slot (cTemplate) template is shown below.
<ejs-grid ref="grid" :dataSource="ds">
<e-columns>
<e-column field="OrderID" headerText="Order ID" width=120 textAlign="Right" />
<e-column field="CustomerName" headerText="Customer Name" width=150 />
<e-column field="ShipCountry" headerText="Ship Country" width=150 :template="'cTemplate'"/>
</e-columns>
<template v-slot:cTemplate="{data}">
<ejs-button :content="data.ShipCountry"></ejs-button>
</template>
</ejs-grid>
The slot template can also be used to insert content into nested tags
within a component. In the below code example, cTemplate
is rendered in the nested tag <e-column>
.
<template>
<div id="grid">
<ejs-grid :dataSource="ds">
<e-columns>
<e-column field="OrderID" headerText="Order ID" width=120 textAlign="Right" />
<e-column field="CustomerName" headerText="Customer Name" width=150 />
<e-column field="ShipCountry" headerText="Ship Country" width=150 :template="'cTemplate'">
<template v-slot:cTemplate="{ data }">
<ejs-button :content="data.ShipCountry"></ejs-button>
</template>
</e-column>
</e-columns>
</ejs-grid>
</div>
</template>
<script setup>
import { GridComponent as EjsGrid, ColumnsDirective as EColumns, ColumnDirective as EColumn } from '@syncfusion/ej2-vue-grids';
import { ButtonComponent as EjsButton } from "@syncfusion/ej2-vue-buttons";
const ds = [
{ OrderID: 10248, ShipCountry: "France", CustomerName: "Paul Henriot" },
{ OrderID: 10249, ShipCountry: "Germany", CustomerName: "Karin Josephs" },
{ OrderID: 10250, ShipCountry: "Brazil", CustomerName: "Mario Pontes" },
{ OrderID: 10251, ShipCountry: "France", CustomerName: "Mary Saveley" }
];
const data = () => { return { ds: empData }; }
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-calendars/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>
<template>
<div id="grid">
<ejs-grid ref="grid" :dataSource="ds">
<e-columns>
<e-column field="OrderID" headerText="Order ID" width=120 textAlign="Right" />
<e-column field="CustomerName" headerText="Customer Name" width=150 />
<e-column field="ShipCountry" headerText="Ship Country" width=150 :template="'cTemplate'">
<template v-slot:cTemplate="{ data }">
<ejs-button :content="data.ShipCountry"></ejs-button>
</template>
</e-column>
</e-columns>
</ejs-grid>
</div>
</template>
<script>
import { ButtonComponent } from '@syncfusion/ej2-vue-buttons';
import { GridComponent } from "@syncfusion/ej2-vue-grids";
var empData = [
{ OrderID: 10248, ShipCountry: "France", CustomerName: "Paul Henriot" },
{ OrderID: 10249, ShipCountry: "Germany", CustomerName: "Karin Josephs" },
{ OrderID: 10250, ShipCountry: "Brazil", CustomerName: "Mario Pontes" },
{ OrderID: 10251, ShipCountry: "France", CustomerName: "Mary Saveley" }
];
export default {
name: "App",
components: {
"ejs-grid": GridComponent,
"e-columns": ColumnsDirective,
"e-column": ColumnDirective,
"ejs-button": ButtonComponent
},
data() { return { ds: empData } }
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-calendars/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>
Inline template
The user can use the app.component
method to add custom content to the template that can be used in the Syncfusion Vue components. The template elements can be added to template
attribute of the app.component
method. Refer to the below code snippet to create the template element using app.component
method.
import { createApp } from "vue/dist/vue.esm-bundler.js";
const app = createApp();
const inlineTemplate = app.component('inlineTemplate', {
components: {
'ejs-button': ButtonComponent
},
data: () => ({}),
template: '<ejs-button :content="`${data.ShipCountry}`"></ejs-button>'
});
Create a template function that returns an object { key: 'template', value: 'importedTemplate' }
to map this template to the Grid component.
const cTemplate = () => {
return { template: inlineTemplate };
}
Now, the template function is assigned to the template
property of the Grid component. Refer to the below example for the inline template.
<template>
<div id="grid">
<ejs-grid ref="grid" :dataSource="ds">
<e-columns>
<e-column field="OrderID" headerText="Order ID" width=120 textAlign="Right" />
<e-column field="CustomerName" headerText="Customer Name" width=150 />
<e-column field="ShipCountry" headerText="Ship Country" width=150 :template='cTemplate' />
</e-columns>
</ejs-grid>
</div>
</template>
<script setup>
import { GridComponent as EjsGrid, ColumnsDirective as EColumns, ColumnDirective as EColumn } from '@syncfusion/ej2-vue-grids';
import { ButtonComponent } from "@syncfusion/ej2-vue-buttons";
import { createApp } from "vue";
const app = createApp();
const inlineTemplate = app.component('inlineTemplate', {
components: {
'ejs-button': ButtonComponent
},
data: () => ({}),
template: '<ejs-button :content="`${data.ShipCountry}`"></ejs-button>'
});
const cTemplate = () => {
return { template: inlineTemplate };
}
const ds = [
{ OrderID: 10248, ShipCountry: "France", CustomerName: "Paul Henriot" },
{ OrderID: 10249, ShipCountry: "Germany", CustomerName: "Karin Josephs" },
{ OrderID: 10250, ShipCountry: "Brazil", CustomerName: "Mario Pontes" },
{ OrderID: 10251, ShipCountry: "France", CustomerName: "Mary Saveley" }
];
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-calendars/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>
<template>
<div id="grid">
<ejs-grid ref="grid" :dataSource="ds">
<e-columns>
<e-column field="OrderID" headerText="Order ID" width=120 textAlign="Right" />
<e-column field="CustomerName" headerText="Customer Name" width=150 />
<e-column field="ShipCountry" headerText="Ship Country" width=150 :template='cTemplate'/>
</e-columns>
</ejs-grid>
</div>
</template>
<script>
import { ButtonComponent } from '@syncfusion/ej2-vue-buttons';
import { GridComponent } from "@syncfusion/ej2-vue-grids";
var inlineTemplate = Vue.component("inlineTemplate", {
template: '<ejs-button :content="`${data.ShipCountry}`"></ejs-button>',
data() { return { data: {} }; }
});
var empData = [
{ OrderID: 10248, ShipCountry: "France", CustomerName: "Paul Henriot" },
{ OrderID: 10249, ShipCountry: "Germany", CustomerName: "Karin Josephs" },
{ OrderID: 10250, ShipCountry: "Brazil", CustomerName: "Mario Pontes" },
{ OrderID: 10251, ShipCountry: "France", CustomerName: "Mary Saveley" }
];
export default {
name: "App",
components: {
"ejs-grid":GridComponent,
"e-columns":ColumnsDirective,
"e-column":ColumnDirective,
"ejs-button":ButtonComponent
},
data () {
return {
ds: empData,
cTemplate: function () {
return { template: inlineTemplate };
}
}
}
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-calendars/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>
External template
The template elements can be defined in an external file (single-file component) and used in Syncfusion Vue components. Refer to the below code snippet to define template elements in template.vue
file.
<template>
<div class="button">
<ejs-button :content="`${data.ShipCountry}`"> </ejs-button>
</div>
</template>
<script setup>
import { defineProps } from 'vue';
import { ButtonComponent as EjsButton } from '@syncfusion/ej2-vue-buttons';
const data = defineProps(['ShipCountry']);
</script>
Import the template.vue
file into the corresponding App.vue
file as specified in the following code snippet.
import template from './template.vue';
Create a template function that returns an object { key: 'template', value: 'importedTemplate' }
to map this template to the Grid component.
const app = createApp();
const externalTemplate = app.component('externalTemplate', template);
const cTemplate = () => {
return { template: externalTemplate };
}
Now, the template function is assigned to the template
property of the Grid component. Refer to the below code snippet from App.vue
file for the external template.
<template>
<div id="app">
<ejs-grid ref="grid" :dataSource="ds">
<e-columns>
<e-column field="OrderID" headerText="Order ID" width=120 textAlign="Right" />
<e-column field="CustomerName" headerText="Customer Name" width=150 />
<e-column field="ShipCountry" headerText="Ship Country" width=150 :template='cTemplate'/>
</e-columns>
</ejs-grid>
</div>
</template>
<script setup>
import { createApp } from "vue";
import { GridComponent as EjsGrid, ColumnsDirective as EColumns, ColumnDirective as EColumn } from "@syncfusion/ej2-vue-grids";
import { ButtonComponent } from "@syncfusion/ej2-vue-buttons";
import template from "./template.vue";
const app = createApp();
const externalTemplate = app.component('externalTemplate', template);
const cTemplate = () => {
return { template: externalTemplate };
}
const ds = [
{ OrderID: 10248, ShipCountry: "France", CustomerName: "Paul Henriot" },
{ OrderID: 10249, ShipCountry: "Germany", CustomerName: "Karin Josephs" },
{ OrderID: 10250, ShipCountry: "Brazil", CustomerName: "Mario Pontes" },
{ OrderID: 10251, ShipCountry: "France", CustomerName: "Mary Saveley" }
];
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-calendars/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>
External modules in templates
Syncfusion provides the option to use external modules in template content. To use the external modules in the template, add those modules to the plugins
property of the Vue component. For example, the “i18n” module is added to the plugins
property of the Grid component. Refer to the below code snippet.
<template>
<h3>Grid component</h3>
<ejs-grid height='210px' :plugins="modules"></ejs-grid>
</template>
<script setup>
import { i18n } from "./main";
import { GridComponent as EjsGrid } from '@syncfusion/ej2-vue-grids';
const modules= [i18n]
</script>
Below is the example code to define i18n
external module in the Vue 3 application.
import { createApp } from 'vue'
import App from './App.vue'
import { createI18n } from "vue-i18n";
const messages = {
en: {
message: {
customer: "Customer Name",
},
},
ja: {
message: {
customer: "顧客名",
},
},
};
export const i18n = createI18n({
legacy: false,
locale: "ja",
fallbackLocale: "en",
messages,
});
createApp(App).use(i18n).mount('#app')
Below is the example code to use i18n
external module in the Grid component template using plugins
property.
<template>
<ejs-grid :dataSource="empData" :plugins="modules">
<e-columns>
<e-column field="OrderID" headerText="Order ID" width=120 textAlign="Right" />
<e-column headerText='Customer Name' width=150 :template="'cTemplate'">
<template v-slot:cTemplate={data}>
<div>{{ $t("message.customer") }} - {{data.CustomerName}}</div>
</template>
</e-column>
</e-columns>
</ejs-grid>
</template>
<script setup>
import { i18n } from "./main";
import { GridComponent as EjsGrid, ColumnsDirective as EColumns, ColumnDirective as EColumn } from '@syncfusion/ej2-vue-grids';
const empData = [
{ OrderID: 10248, ShipCountry: "France", CustomerName: "Paul Henriot" },
{ OrderID: 10249, ShipCountry: "Germany", CustomerName: "Karin Josephs" },
{ OrderID: 10250, ShipCountry: "Brazil", CustomerName: "Mario Pontes" },
{ OrderID: 10251, ShipCountry: "France", CustomerName: "Mary Saveley" }
];
const modules= [i18n];
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-calendars/styles/material.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/material.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/material.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/material.css";
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>
Provide/Inject in templates
In Vue, provide
and inject
options are used to share data between components that are not directly related through a parent-child relationship.
Syncfusion components can use these provide
and inject
options in templates. It allows to pass data from a parent component to its template components without having to pass props down the component tree. Instead, the parent component provides the data, and the child components inject it.
To provide data from a parent component to its template, use the provide
option. The provide option is an object that contains the data to provide. The keys in the object are the names of the properties, and the values are the data to provide.
In this below example, the parent component provides the content property with the value of Update
in App.vue file.
<template>
<div id="grid">
<ejs-grid ref="grid" :dataSource="ds">
<e-columns>
<e-column field="OrderID" headerText="Order ID" width=120 textAlign="Right" />
<e-column field="CustomerName" headerText="Customer Name" width=150 />
<e-column field="ShipCountry" headerText="Ship Country" width=150 :template="'cTemplate'">
<template v-slot:cTemplate={data}>
<div> <MyTemplate /></div>
</template>
</e-column>
</e-columns>
</ejs-grid>
</div>
</template>
<script setup>
import { provide } from 'vue';
import { GridComponent as EjsGrid, ColumnsDirective as EColumns, ColumnDirective as EColumn } from '@syncfusion/ej2-vue-grids';
import MyTemplate from "./MyTemplate.vue";
var empData = [
{ OrderID: 10248, ShipCountry: "France", CustomerName: "Paul Henriot" },
{ OrderID: 10249, ShipCountry: "Germany", CustomerName: "Karin Josephs" },
{ OrderID: 10250, ShipCountry: "Brazil", CustomerName: "Mario Pontes" },
{ OrderID: 10251, ShipCountry: "France", CustomerName: "Mary Saveley" }
];
provide('content', 'Update');
</script>
To inject data provided by a parent component, use the inject
option. The inject
option is an array or an object that contains the names of the properties to inject.
In this below example, the child template component injects content property using the inject
option, and displays its value using an interpolation directive ({{ content }}) in MyTemplate.vue file.
<template>
<ejs-button>{{ content }}</ejs-button>
</template>
<script>
import { inject } from 'vue';
import { ButtonComponent as EjsButton } from '@syncfusion/ej2-vue-buttons';
const content = inject('content');
</script>