13

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?

1
  • Instead of passing in two props you could also just get the columns by using Object.keys like this: <th v-for="(column, index) in Object.keys(items)" :key="index">{{column}}</th> Commented May 20, 2021 at 18:58

2 Answers 2

21

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>
Sign up to request clarification or add additional context in comments.

Comments

3

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.