Search results

Template

02 Dec 2022 / 9 minutes to read

Slots

Slot Content

The slot support is available in Vue which will render the component. It loads the outlet content into DOM.

Slot support will reduce property usage and new component creation. It will increase the readability of the component and reduce the code usage of the components. Slots is mainly used for single-page applications which helps the template’s reusability. The Syncfusion Vue components allow rendering templates using slots.

Render Scope

In a single-page application, there may be a need to access the parent component scope. The slot content has access to the data scope of the parent component.

The props passed to the slot by the component’s data source ({data}) is available as the value of the corresponding v-slot directive, which can be accessed by expressions inside the slot.

Copied to clipboard
<template v-slot:templateName="{data}">
</template>
  • Template sample with data scope in the slot.
Copied to clipboard
<template>
  <div class="col-lg-12 control-section">
<div>
  <ejs-grid :dataSource="data" height=335 width='auto' :rowTemplate="'rowTemplate'" >
    <e-columns>
      <e-column field='Employee Image' headerText='Employee Image' width='150' textAlign='Center'></e-column>
      <e-column field='Employee Details' headerText='Employee Details' width='300' textAlign='Left'></e-column>
    </e-columns>
    <template v-slot:rowTemplate="{data}">
      <tr>
        <td class="details">
          <table class="CardTable" cellpadding="3" cellspacing="2">
            <colgroup>
              <col width="50%">
              <col width="50%">
            </colgroup>
            <tbody>
              <tr>
                <td class="CardHeader">First Name </td>
                <td>{{data.FirstName}} </td>
              </tr>
              <tr>
                <td class="CardHeader">Last Name</td>
                <td>{{data.LastName}} </td>
              </tr>
              <tr>
                <td class="CardHeader">Title</td>
                <td>{{data.Title}} </td>
              </tr>
              <tr>
                <td class="CardHeader">Birth Date</td>
                <td>{{format(data.BirthDate)}} </td>
              </tr>
              <tr>
                <td class="CardHeader">Hire Date</td>
                <td>{{format(data.HireDate)}} </td>
              </tr>
            </tbody>
          </table>
        </td>
      </tr>
    </template>
  </ejs-grid>
</div>
  </div>
</template>
<style>
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
.details {
  border-color: #e0e0e0;
  border-style: solid;
}

.details {
  border-width: 1px 0px 0px 0px;
  padding-left: 18px;
}

.details > table {
  width: 100%;
}

.CardHeader {
  font-weight: bolder;
}

td {
  padding: 2px 2px 3px 4px;
}
</style>

<script>
import Vue from "vue";
import { GridPlugin } from "@syncfusion/ej2-vue-grids";
import { Internationalization } from '@syncfusion/ej2-base';


Vue.use(GridPlugin);

let instance = new Internationalization();

export default Vue.extend({
  data: () => {
return {
  data: [{
    'EmployeeID': 1,
    'LastName': 'Davolio',
    'FirstName': 'Nancy',
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-664743600000),
    'HireDate': new Date(704692800000)
  }, {
    'EmployeeID': 2,
    'LastName': 'Fuller',
    'FirstName': 'Andrew',
    'Title': 'Vice President, Sales',
    'TitleOfCourtesy': 'Dr.',
    'BirthDate': new Date(-563828400000),
    'HireDate': new Date(713764800000),
  }];
};
  },
  methods: {
format: function(value) {
    return instance.formatDate(value, { skeleton: 'yMd', type: 'date' });
}
  }
});
</script>

Named Slots

The Syncfusion Vue components support multiple templates. Each template is differentiated by its name. Each slot’s name needs to map with the corresponding property name to render the slot content to the corresponding slot outlet.

Copied to clipboard
<template v-slot:templateName>
</template>
  • You need to map the slot name to the component’s property as a string value. In the following sample, the rowTemplate is passed as a slot name in Grid rowTemplate property.
Copied to clipboard
<template>
  <div class="col-lg-12 control-section">
<div>
  <ejs-grid :dataSource="data" height=335 width='auto' :rowTemplate="'rowTemplate'" >
    <e-columns>
      <e-column field='Employee Details' headerText='Employee Details' width='300' textAlign='Left'></e-column>
    </e-columns>
    <template v-slot:rowTemplate="{data}">
      <tr>
        <td class="details">
          <table class="CardTable" cellpadding="3" cellspacing="2">
            <colgroup>
              <col width="50%">
              <col width="50%">
            </colgroup>
            <tbody>
              <tr>
                <td class="CardHeader">First Name </td>
                <td>{{data.FirstName}} </td>
              </tr>
              <tr>
                <td class="CardHeader">Last Name</td>
                <td>{{data.LastName}} </td>
              </tr>
              <tr>
                <td class="CardHeader">Title</td>
                <td>{{data.Title}} </td>
              </tr>
              <tr>
                <td class="CardHeader">Birth Date</td>
                <td>{{format(data.BirthDate)}} </td>
              </tr>
              <tr>
                <td class="CardHeader">Hire Date</td>
                <td>{{format(data.HireDate)}} </td>
              </tr>
            </tbody>
          </table>
        </td>
      </tr>
    </template>
  </ejs-grid>
</div>
  </div>
</template>
<style>
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
.details {
  border-color: #e0e0e0;
  border-style: solid;
}

.details {
  border-width: 1px 0px 0px 0px;
  padding-left: 18px;
}

.details > table {
  width: 100%;
}

.CardHeader {
  font-weight: bolder;
}

td {
  padding: 2px 2px 3px 4px;
}
</style>

<script>
import Vue from "vue";
import { GridPlugin } from "@syncfusion/ej2-vue-grids";
import { Internationalization } from '@syncfusion/ej2-base';


Vue.use(GridPlugin);

let instance = new Internationalization();

export default Vue.extend({
  data: () => {
return {
  data: [{
    'EmployeeID': 1,
    'LastName': 'Davolio',
    'FirstName': 'Nancy',
    'Title': 'Sales Representative',
    'TitleOfCourtesy': 'Ms.',
    'BirthDate': new Date(-664743600000),
    'HireDate': new Date(704692800000)
  }, {
    'EmployeeID': 2,
    'LastName': 'Fuller',
    'FirstName': 'Andrew',
    'Title': 'Vice President, Sales',
    'TitleOfCourtesy': 'Dr.',
    'BirthDate': new Date(-563828400000),
    'HireDate': new Date(713764800000)
  }];
};
  },
  methods: {
format: function(value) {
    return instance.formatDate(value, { skeleton: 'yMd', type: 'date' });
}
  }
});
</script>
  • The slot template can be added to nested tags also. In the below code example, cTemplate is rendered in nested tag <e-column>.
Copied to clipboard
<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-columns>
</ejs-grid>
  </div>
</template>
<script>
import Vue from 'vue';
import { ButtonPlugin } from '@syncfusion/ej2-vue-buttons';
import { GridPlugin } from "@syncfusion/ej2-vue-grids";

Vue.use(GridPlugin);
Vue.use(ButtonPlugin);

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 {
  data () {
return {
 ds: empData
}
  }
}
</script>
<style>
  @import "../node_modules/@syncfusion/ej2-vue-buttons/styles/material.css";
  @import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>

Sample

Source
Preview
app.vue
Copied to clipboard
<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-columns>
</ejs-grid>
  </div>
</template>
<script>
import Vue from 'vue';
import { ButtonPlugin } from '@syncfusion/ej2-vue-buttons';
import { GridPlugin } from "@syncfusion/ej2-vue-grids";

Vue.use(GridPlugin);
Vue.use(ButtonPlugin);

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 {
  data () {
return {
 ds: empData
}
  }
}
</script>
<style>
  @import "../node_modules/@syncfusion/ej2-vue-buttons/styles/material.css";
  @import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>

Template

The Syncfusion Vue UI components support native Vue templates using single file components and Vue.component().

The two ways to configure template support are:

  • Single File Components (.vue file)
  • Vue.component()

Single file components

  • Define the template in a template.vue file, and create an empty object data in the data option of the template.vue file.
  • Pass arguments as properties of a data object.

Refer to the following code snippet of template.vue file.

Copied to clipboard
// template.vue

<template>
  <div class="button">
<ejs-button  :content="`${data.ShipCountry}`"></ejs-button>
  </div>
</template>

<script>

export default {
  data () {
return {
    data: {}
}
  }
}
</script>
  • Import the template.vue file in the corresponding app.vue file as specified in the following code snippet.
Copied to clipboard
import buttonTemplate from './template.vue'
  • Create a template function which returns an object { key: ‘template’, value: ‘importedTemplate’ }.
Copied to clipboard
cTemplate: function(e) {
   return {
   template: buttonTemplate
   };
}
  • Template function is assigned to the template property of the Syncfusion Vue component.

Refer to the following code snippet of App.vue file.

Copied to clipboard
// App.vue

<template>
  <div id="app">
  <ejs-grid ref="grid" :dataSource="ds">
            <e-columns>
                <e-column headerText='Ship Country' width='150' textAlign='Center' :template='cTemplate' />
                <e-column field="OrderID" headerText="Order ID" width=120 textAlign="Right" />
                <e-column field="CustomerName" headerText="Customer Name" width=150 />
            </e-columns>
        </ejs-grid>
  </div>
</template>
<script>
import Vue from "vue";
import { GridPlugin } from "@syncfusion/ej2-vue-grids";
import { empData } from "./data";
import buttonTemplate from "./template.vue";

Vue.use(GridPlugin);

export default {
  data() {
return {
  ds: empData,
  cTemplate: function(e) {
    return {
      template: buttonTemplate
    };
  }
};
  }
};
</script>

<style>
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>

Vue.component()

The template is initialized with Vue.component() where template is provided with the template option.

  • The template is initialized with Vue.component() where template is provided with the template option.
  • Pass arguments as properties of a data object.
Copied to clipboard
var demoTemplate = Vue.component("demo", {
  template: "<ejs-button :content="`${data.ShipCountry}`"></ejs-button>",
  data() {
return {
  data: {}
};
  }
});
  • Create a template function which returns an object { key: ‘template’, value: ‘importedTemplate’ }.
Copied to clipboard
cTemplate: function(e) {
   return {
   template: demoTemplate
   };
}
  • Template function is assigned to the template property of the Syncfusion Vue component.
  • Refer to the following code snippet of App.vue file.
Copied to clipboard
// App.vue

<template>
  <div id="app">
  <ejs-grid ref="grid" :dataSource="ds">
            <e-columns>
                <e-column headerText='Ship Country' width='150' textAlign='Center' :template='cTemplate' />
                <e-column field="OrderID" headerText="Order ID" width=120 textAlign="Right" />
                <e-column field="CustomerName" headerText="Customer Name" width=150 />
            </e-columns>
        </ejs-grid>
  </div>
</template>
<script>
import Vue from "vue";
import { GridPlugin } from "@syncfusion/ej2-vue-grids";
import { empData } from "./data";

Vue.use(GridPlugin);

var demoTemplate = Vue.component("demo", {
  template: "<ejs-button>{{data.ShipCountry}}</ejs-button>",
  data() {
return {
  data: {}
};
  }
});

export default {
  data() {
return {
  ds: empData,
  cTemplate: function(e) {
    return {
      template: demoTemplate
    };
  }
};
  }
};
</script>

<style>
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>

Template sample

Source
Preview
app.vue
Copied to clipboard
<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 Vue from 'vue';
import { ButtonPlugin } from '@syncfusion/ej2-vue-buttons';
import { GridPlugin } from "@syncfusion/ej2-vue-grids";

Vue.use(GridPlugin);
Vue.use(ButtonPlugin);


var demoTemplate = Vue.component("demo", {
  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 {
  data () {
return {
  ds: empData,
  cTemplate: function (e) {
    return {
      template: demoTemplate
    };
  }
}
  }
}
</script>
<style>
  @import "../node_modules/@syncfusion/ej2-vue-buttons/styles/material.css";
  #app {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
  }
</style>

External modules in templates

Syncfusion template components has option to use the external modules functionality in template content. To pass the external modules in template, you have to use the plugin property. For example, to add the i18n module in component template, refer below code snippets.

Copied to clipboard
<template>
  <h3>Grid component</h3>
  <ejs-grid height='210px' :allowPaging="true" :plugins="modules">
  </ejs-grid>
</template>

<script>
import { GridPlugin } from "@syncfusion/ej2-vue-grids";

Vue.use(GridPlugin);

export default {
  setup() {
return {
  modules: [i18n, router, store]
};
  }
};
</script>

Here, We have demonstrated the sample for localization in templates.

Source
Preview
app.vue
Copied to clipboard
<template>
  <h3>Grid component</h3>
  <ejs-grid :dataSource='data' height='210px' :allowPaging="true" :plugins="modules">
<e-columns>
  <e-column field='OrderID' headerText='Order ID' textAlign='right' width=120></e-column>
  <e-column field='CustomerID' headerText='Customer ID' width=150></e-column>
  <e-column headerText='Template' :template="'colLinkTemplate1'" textAlign='right' width='80'>
    <template v-slot:colLinkTemplate1={}>
      <div>
        {{ $t("message.hello") }}
      </div>
    </template>
  </e-column>
</e-columns>
  </ejs-grid>
</template>

<script>
import { GridPlugin } from "@syncfusion/ej2-vue-grids";
import Vue from 'vue';
import { createI18n } from "vue-i18n";

Vue.use(GridPlugin);

const messages = {
  en: {
message: {
  hello: "hello world",
},
  },
  ja: {
message: {
  hello: "こんにちは、世界",
},
  },
};

export const i18n = createI18n({
  legacy: false,
  locale: "ja",
  fallbackLocale: "en",
  messages,
});

export default {
  setup() {
return {
  modules: [i18n],
  data: [
  {
    OrderID: 10248,
    CustomerID: "VINET",
    ShipCountry: "France",
  },
  {
    OrderID: 10249,
    CustomerID: "TOMSP",
    ShipCountry: "Germany",
  },]
};
  }
};
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/material.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/material.css";
@import "../node_modules/@syncfusion/ej2-vue-lists/styles/material.css";
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/material.css";
</style>