Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create dynamic table component Vue JS

I'm learning Vue JS. I want to create a component to show data with table that I can reuse in other components. I have 2 props items(data) and columns(column name)

items: [
        {
            'id':'1',
            'title': 'hello',
            'description': 'ok ok',
            'created_date': '2018-09-09'
        },
        {
            'id':'2',
            'title': 'hello 2',
            'description': 'ok ok 2',
            'created_date': '2018-10-09'
        }
    ],
    columns: [ 'id', 'title', 'description', 'created_date']

I want to create a table as bellow

<table class="table">
<thead>
    <tr>
        <th v-for="(column, index) in columns" :key="index"> {{column}}</th>
    </tr>
</thead>
<tbody>
    <tr v-for="(item, index) in items" :key="index">
        <td v-for="(column, indexColumn) in columns" :key="indexColumn">{{item.$column}}</td>
    </tr>
</tbody>

I don't know how to get value from item by column name. Is it possible to create a table like this?

like image 895
user3181303 Avatar asked Oct 26 '18 10:10

user3181303


2 Answers

Everything is fine just change the value in the template item.$column to item[column]

   <table class="table">
      <thead>
          <tr>
              <th v-for="(column, index) in columns" :key="index"> {{column}}</th>
          </tr>
      </thead>
      <tbody>
          <tr v-for="(item, index) in items" :key="index">
              <td v-for="(column, indexColumn) in columns" :key="indexColumn">{{item[column]}}</td>
          </tr>
      </tbody>
    </table>
like image 177
Saravanan Avatar answered Nov 13 '22 11:11

Saravanan


TABLE COMPONENT WITH DYNAMIC SLOTS

I've created a a simple component for dynamic table with slot option.

<template>
  <div id="appTable">
    <table>
      <thead>
        <tr>
          <th v-for="(header, i) in headers" :key="i">
            {{ header }}
          </th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(item, i) of data" :key="i">
          <td v-for="(td, j) of slotsProceced" :key="i + '-' + j">
            <slot v-if="td.hasSlot" :name="td.slotName" :item="item" />
            <span v-else>{{ item[td.key] }}</span>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'AppTable',
  props: {
    headers: {
      type: Object,
      required: true
    },
    data: {
      type: Array,
      required: true
    }
  },
  setup(props, { slots }) {
    const slotsProceced = [];
    for (const key in props.headers) {
      if (Object.prototype.hasOwnProperty.call(props.headers, key)) {
        const slotName = 'item-' + key;
        slotsProceced.push({
          key: key,
          hasSlot: !!slots[slotName],
          slotName: slotName
        });
      }
    }

    return { slotsProceced };
  }
});
</script>

The props to call:

const headTable = {
  date: "Date",
  price: "Price",
  status: "Status",
  action: "Action",
};
const dataTable = [
  {
    date: "2021-02-03 22:04:16",
    price: "$32.000",
    status: 1,
  },
];

To call it:

<AppTable :headers="headTable" :data="dataTable">
  <template v-slot:item-action>
    <span>Some Action</span>
  </template>
  <template v-slot:item-status="{ item }">
    <span>{{ item.status === 1 ? 'Active' : 'Inactive' }}</span>
  </template>
</AppTable>
like image 1
Juan Aguillón Avatar answered Nov 13 '22 10:11

Juan Aguillón