How do i pass components as a slot to from parent component?

How do i pass components as a slot to from parent component?

casperxcasperx Posts: 4Questions: 1Answers: 0

Package Version:

"dependencies": {
    "datatables.net-dt": "^2",
    "datatables.net-vue3": "^3",
    "vue": "^3.2.37"
  },

Description of problem:
Hi there,

I am using vue3 and I am trying to create a reusable component for DataTables.
The issue i am currently facing is that, I am not able to create custom slots from the parent component.
It only works if i define the slots within the DataTable Component itself.

What i am trying to achieve is to make the DataTable component to support dynamic slots.
I've tried a few ways to get this working but I am not able to achieve it and I am pretty new to VueJS too.

My previous reference in order to confirm that slots are working fine is by referring to this discussion:
https://datatables.net/forums/discussion/79326/loading-vue-component-as-slot-new-release

Hopefully somebody can guide me on this. Thank you.

App.vue

<script setup lang="ts">
import VDataTables from './components/VDataTables.vue';
</script>
<template>
  <VDataTables
    :columns="[
      { data: 'name' },
      { data: 'position' },
      { data: 'office' },
      { data: 'extn' },
      { data: 'start_date' },
      { data: 'salary' },
    ]"
    :options="{
      columnDefs: [
        {
          target: -1,
          render: '#action',
          data: null,
        },
      ],
    }"
    customSlots="['action']"
    url="/data.json"
  >
    <!-- Loop isnt working or defined wrongly? -->
    <template #action="props"> $$$$ {{ props.cellData }} </template>
  </VDataTables>
</template>

<style>
@import 'datatables.net-dt';
</style>

VDataTAbles.vue

<script setup lang="ts">
import DataTable from 'datatables.net-vue3';
import DataTablesCore from 'datatables.net';

const myProps = defineProps({
  columns: {
    type: Array,
    required: true,
  },
  url: {
    type: String,
    default: '',
  },
  options: {
    type: Array,
    default: [],
  },
  customSlots: {
    type: Array,
    default: [],
  },
});

DataTable.use(DataTablesCore);
</script>

<template>
  <div>
    <h1>Ajax data source table</h1>
    <h2>DataTables + Vue3 example</h2>
    <p>
      In this example the <code>datatables.net-vue3</code> package is used to
      load JSON data and display it in an interactive table. In this case we use
      object based row data, rather than arrays, so the
      <code>columns</code> option is specified to tell DataTables which property
      to read from the objects for each column.
    </p>

    <DataTable
      :columns="columns"
      :ajax="url"
      class="display"
      width="100%"
      :options="options"
    >
      <thead>
        <tr>
          <th>Name</th>
          <th>Position</th>
          <th>Office</th>
          <th>Extn.</th>
          <th>Start date</th>
          <th>Salary</th>
        </tr>
      </thead>
      <tfoot>
        <tr>
          <th>Name</th>
          <th>Position</th>
          <th>Office</th>
          <th>Extn.</th>
          <th>Start date</th>
          <th>Salary</th>
        </tr>
      </tfoot>

      <!-- Loop isnt working or defined wrongly? -->
      <template v-for="slotName in customSlots" #[slotName]="slotProps">
        {{ console.log(`Rendering slot: ${slotName}`, slotProps) }}
        <slot :slot:[`${slotName}`]="slotProps"></slot>
      </template>
    </DataTable>
  </div>
</template>

<style>
@import 'datatables.net-dt';
</style>

Answers

  • allanallan Posts: 64,010Questions: 1Answers: 10,554 Site admin

    I fear you've probably gone beyond my Vue knowledge with this one. You might need to ask on SO or some Vue specific discussion forum. Vue 3 does have dynamic slot name support, so if you define the slot names correctly, that it might work? If you can create a test case on StackBlitz that might help with the debugging.

    Allan

  • casperxcasperx Posts: 4Questions: 1Answers: 0

    Hi @allan haha. Thank you for taking your time to entertain this issue.

    Here's a forked version of one of the existing StackBlitz app just incase if you would like to also look into it :D
    https://stackblitz.com/edit/datatables-net-vue3-simple-zmy4nfmc?file=src%2FApp.vue,src%2Fcomponents%2FVDataTables.vue,public%2Fdata.json

    For some reason StackBlitz doesnt allow me to console.log within the template tag but on local it works.

    Also, noted on seeking from SO or Vue specific forums. Ill definitely post it on SO within a week time just to ensure I am not spamming every forum.

    Thank you.

  • casperxcasperx Posts: 4Questions: 1Answers: 0

    I've got it to work as how i intended it to work after giving some time testing out on dynamic slots from vue docs.

    https://stackblitz.com/edit/datatables-net-vue3-simple-zmy4nfmc?file=src%2FApp.vue,src%2Fcomponents%2FVDataTables.vue,public%2Fdata.json

    Thought of sharing it here.

    Within the VDataTables.vue component:

    <!-- For dynamic slots -->
    
    <template v-for="slotName in customSlots" #[slotName]="slotProps">
                <slot :name="slotName" v-bind="slotProps"></slot>
     </template>
    

    Within the App.vue component:

    <template #action="props">
           <span>Custom Slot 1: {{ props.cellData.id }}</span>
    </template>
    

    Thanks !

  • allanallan Posts: 64,010Questions: 1Answers: 10,554 Site admin

    That's superb - nice one!!

    And thanks for sharing the solution with us as well.

    Allan

  • casperxcasperx Posts: 4Questions: 1Answers: 0

    You are welcome allan!

Sign In or Register to comment.