{"id":13701398,"url":"https://github.com/spatie/vue-table-component","last_synced_at":"2025-05-04T21:30:52.541Z","repository":{"id":57113450,"uuid":"92080158","full_name":"spatie/vue-table-component","owner":"spatie","description":"A straight to the point Vue component to display tables","archived":true,"fork":false,"pushed_at":"2018-10-24T11:23:05.000Z","size":765,"stargazers_count":582,"open_issues_count":0,"forks_count":149,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-04-19T10:38:32.175Z","etag":null,"topics":["component","html","table","vue"],"latest_commit_sha":null,"homepage":"http://vue-table-component.spatie.be","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spatie.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-22T17:24:10.000Z","updated_at":"2025-03-11T18:21:55.000Z","dependencies_parsed_at":"2022-08-22T04:10:58.526Z","dependency_job_id":null,"html_url":"https://github.com/spatie/vue-table-component","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Fvue-table-component","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Fvue-table-component/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Fvue-table-component/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spatie%2Fvue-table-component/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spatie","download_url":"https://codeload.github.com/spatie/vue-table-component/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252403776,"owners_count":21742438,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["component","html","table","vue"],"created_at":"2024-08-02T20:01:35.392Z","updated_at":"2025-05-04T21:30:52.058Z","avatar_url":"https://github.com/spatie.png","language":"JavaScript","readme":"🚨 **THIS PACKAGE HAS BEEN ABANDONED** 🚨\n\nWe don't use this package anymore in our own projects and cannot justify the time needed to maintain it anymore. That's why we have chosen to abandon it. Feel free to fork our code and maintain your own copy or use one of the many alternatives.\n\n# A straightforward Vue component to filter and sort tables\n\n[![Latest Version on NPM](https://img.shields.io/npm/v/vue-table-component.svg?style=flat-square)](https://npmjs.com/package/vue-table-component)\n[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)\n[![Build Status](https://img.shields.io/travis/spatie/vue-table-component/master.svg?style=flat-square)](https://travis-ci.org/spatie/vue-table-component)\n[![npm](https://img.shields.io/npm/dt/vue-table-component.svg?style=flat-square)](https://www.npmjs.com/package/vue-table-component)\n\n---\n\n🚨 **WARNING: FEATURE FREEZE** 🚨\n\nVersion 1 of this package has become very hard to maintain due to the way it's built up. We also have too many feature requests, which we can't all cater too. We're working on v2 of this package, and won't be adding any new features or accepting feature PR's for v1.\n\n---\n\nThis repo contains a Vue component that can render a filterable and sortable table. It aims to be very lightweight and easy to use. It has support for [retrieving data asynchronously and pagination](#retrieving-data-asynchronously).\n\nHere's an example of how you can use it:\n\n```html\n\u003ctable-component\n     :data=\"[\n          { firstName: 'John', lastName: 'Lennon', instrument: 'Guitar', birthday: '04/10/1940', songs: 72 },\n          { firstName: 'Paul', lastName: 'McCartney', instrument: 'Bass', birthday: '18/06/1942', songs: 70 },\n          { firstName: 'George', lastName: 'Harrison', instrument: 'Guitar', birthday: '25/02/1943', songs: 22 },\n          { firstName: 'Ringo', lastName: 'Starr', instrument: 'Drums', birthday: '07/07/1940', songs: 2 },\n     ]\"\n     sort-by=\"songs\"\n     sort-order=\"asc\"\n\u003e\n     \u003ctable-column show=\"firstName\" label=\"First name\"\u003e\u003c/table-column\u003e\n     \u003ctable-column show=\"lastName\" label=\"Last name\"\u003e\u003c/table-column\u003e\n     \u003ctable-column show=\"instrument\" label=\"Instrument\"\u003e\u003c/table-column\u003e\n     \u003ctable-column show=\"songs\" label=\"Songs\" data-type=\"numeric\"\u003e\u003c/table-column\u003e\n     \u003ctable-column show=\"birthday\" label=\"Birthday\" data-type=\"date:DD/MM/YYYY\"\u003e\u003c/table-column\u003e\n     \u003ctable-column label=\"\" :sortable=\"false\" :filterable=\"false\"\u003e\n         \u003ctemplate slot-scope=\"row\"\u003e\n            \u003ca :href=\"`#${row.firstName}`\"\u003eEdit\u003c/a\u003e\n         \u003c/template\u003e\n     \u003c/table-column\u003e\n \u003c/table-component\u003e\n```\n\nA cool feature is that the table caches the used filter and sorting for 15 minutes. So if you refresh the page, the filter and sorting will still be used.\n\n## Demo\n\nWant to see the component in action? No problem. [Here's a demo](http://vue-table-component.spatie.be).\n\n## Installation\n\nYou can install the package via yarn:\n\n```bash\nyarn add vue-table-component\n```\n\nor npm:\n\n```bash\nnpm install vue-table-component --save\n```\n\nNext, you must register the component. The most common use case is to do that globally.\n\n```js\n//in your app.js or similar file\nimport Vue from 'vue';\nimport { TableComponent, TableColumn } from 'vue-table-component';\n\nVue.component('table-component', TableComponent);\nVue.component('table-column', TableColumn);\n```\n\nAlternatively you can do this to register the components:\n\n```js\nimport TableComponent from 'vue-table-component';\n\nVue.use(TableComponent);\n```\n\n## Browser Support\n\n`vue-table-component` has the same browser support as Vue (see https://github.com/vuejs/vue). However, you might need to polyfill the [`Array.prototype.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find#Polyfill) method for IE support.\n\n## Usage\n\nHere's a simple example on how to use the component.\n\n```html\n\u003ctable-component\n     :data=\"[\n     { firstName: 'John', birthday: '04/10/1940', songs: 72 },\n     { firstName: 'Paul', birthday: '18/06/1942', songs: 70 },\n     { firstName: 'George', birthday: '25/02/1943', songs: 22 },\n     { firstName: 'Ringo', birthday: '07/07/1940', songs: 2 },\n     ]\"\n     sort-by=\"songs\"\n     sort-order=\"asc\"\n     \u003e\n     \u003ctable-column show=\"firstName\" label=\"First name\"\u003e\u003c/table-column\u003e\n     \u003ctable-column show=\"songs\" label=\"Songs\" data-type=\"numeric\"\u003e\u003c/table-column\u003e\n     \u003ctable-column show=\"birthday\" label=\"Birthday\" :filterable=\"false\" data-type=\"date:DD/MM/YYYY\"\u003e\u003c/table-column\u003e\n \u003c/table-component\u003e\n```\n\nThis will render a table that is both filterable and sortable. A filter field will be displayed right above the table. If your data contains any html we will filter that out when filtering. You can sort the table by clicking on the column headers. By default it will remember the used filter and sorting for the next 15 minutes.\n\n### Props\n\nYou can pass these props to `table-component`:\n\n- `data`: (required) the data the component will operate on. This can either be an array or [a function](#retrieving-data-asynchronously)\n- `show-filter`: set this to `false` to not display the `filter` field.\n- `show-caption`: set this to `false` to not display the `caption` field which shows the current active filter.\n- `sort-by`: the property in data on which to initially sort.\n- `sort-order`: the initial sort order.\n- `cache-lifetime`: the lifetime in minutes the component will cache the filter and sorting.\n- `cache-key`: if you use multiple instances of `table-component` on the same page you must set this to a unique value per instance.\n- `table-class`: the passed value will be added to the `class` attribute of the rendered table\n- `thead-class`: the passed value will be added to the `class` attribute of the rendered table head.\n- `tbody-class`: the passed value will be added to the `class` attribute of the rendered table body.\n- `filter-placeholder`: the text used as a placeholder in the filter field\n- `filter-input-class`: additional classes that you will be applied to the filter text input\n- `filter-no-results`: the text displayed when the filtering returns no results\n\nFor each `table-column` a column will be rendered. It can have these props:\n\n- `show`: (required) the property name in the data that needs to be shown in this column.\n- `formatter`: a function the will receive the value that will be displayed and all column properties. The return value of this function will be displayed. Here's [an example](#formatting-values)\n- `label`: the label that will be shown on top of the column. Set this to an empty string to display nothing. If this property is not present, the string passed to `show` will be used.\n- `data-type`: if your column should be sorted numerically set this to `numeric`. If your column contains dates set it to `date:` followed by the format of your date\n- `sortable`: if you set this to `false` then the column won't be sorted when clicking the column header\n- `sort-by`: you can set this to any property present in `data`. When sorting the column that property will be used to sort on instead of the property in `show`.\n- `filterable`: if this is set to `false` than this column won't be used when filtering\n- `filter-on`: you can set this to any property present in `data`. When filtering the column that property will be used to filter on instead of the property in `show`.\n- `hidden`: if you set this to `true` then the column will be hidden. This is useful when you want to sort by a field but don't want it to be visible.\n- `header-class`: the passed value will be added to the `class` attribute of the columns `th` element.\n- `cell-class`: the passed value will be added to the `class` attribute of the columns `td` element.\n\n## Listeners\n\nThe `table-component` currently emits one custom event:\n\n- `@rowClick`: is fired when a row is clicked. Receives the row data as it's event payload.\n\n### Modifying the used texts and CSS classes\n\nIf you want to modify the built in text or classes you can pass settings globally.\nYou can use the [CSS](docs/table-component.css) from the docs as a starting point for your own styling.\n\n```js\nimport TableComponent from 'vue-table-component';\n\nTableComponent.settings({\n    tableClass: '',\n    theadClass: '',\n    tbodyClass: '',\n    filterPlaceholder: 'Filter table…',\n    filterNoResults: 'There are no matching rows',\n});\n```\n\nYou can also provide the custom settings on Vue plugin install hook:\n\n```js\nimport Vue from 'vue';\nimport TableComponent from 'vue-table-component';\n\nVue.use(TableComponent, {\n    tableClass: '',\n    theadClass: '',\n    tbodyClass: '',\n    filterPlaceholder: 'Filter table…',\n    filterNoResults: 'There are no matching rows',\n});\n```\n\n## Retrieving data asynchronously\n\nThe component can fetch data in an asynchronous manner. The most common use case for this is fetching data from a server.\n\nTo use the feature you should pass a function to the `data` prop. The function will receive an object with `filter`, `sort` and `page`. You can use these parameters to fetch the right data. The function should return an object with the following properties:\n\n- `data`: (required) the data that should be displayed in the table.\n- `pagination`: (optional) this should be an object with keys `currentPage` and `totalPages`. If `totalPages` is higher than 1 pagination links will be displayed.\n\nHere's an example:\n\n```html\n\u003ctemplate\u003e\n   \u003cdiv id=\"app\"\u003e\n       \u003ctable-component :data=\"fetchData\"\u003e\n           \u003ctable-column show=\"firstName\" label=\"First name\"\u003e\u003c/table-column\u003e\n       \u003c/table-component\u003e\n   \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\n    import axios from 'axios';\n\n    export default {\n        methods: {\n            async fetchData({ page, filter, sort }) {\n                const response = await axios.get('/my-endpoint', { page });\n\n                // An object that has a `data` and an optional `pagination` property\n                return response;\n            }\n        }\n    }\n\u003c/script\u003e\n```\n\nIf you for some reason need to manually refresh the table data, you can call the `refresh` method on the component.\n\n```html\n\u003ctable-component :data=\"fetchData\" ref=\"table\"\u003e\n    \u003c!-- Columns... --\u003e\n\u003c/table-component\u003e\n```\n\n```js\nthis.$refs.table.refresh();\n```\n\n## Formatting values\n\nYou can format values before they get displayed by using scoped slots. Here's a quick example:\n\n```html\n\u003ctable-component\n     :data=\"[\n          { firstName: 'John', songs: 72 },\n          { firstName: 'Paul', songs: 70 },\n          { firstName: 'George', songs: 22 },\n          { firstName: 'Ringo', songs: 2 },\n     ]\"\n\u003e\n\n     \u003ctable-column label=\"My custom column\" :sortable=\"false\" :filterable=\"false\"\u003e\n         \u003ctemplate slot-scope=\"row\"\u003e\n            {{ row.firstName }} wrote {{ row.songs }} songs.\n         \u003c/template\u003e\n     \u003c/table-column\u003e\n \u003c/table-component\u003e\n```\n\nAlternatively you can pass a function to the `formatter` prop. Here's an example Vue component that uses the feature.\n\n```vue\n\u003ctemplate\u003e\n    \u003ctable-component\n        :data=\"[{ firstName: 'John' },{ firstName: 'Paul' }]\"\u003e\n        \u003ctable-column show=\"firstName\" label=\"First name\" :formatter=\"formatter\"\u003e\u003c/table-column\u003e\n    \u003c/table-component\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nexport default {\n    methods: {\n        formatter(value, rowProperties) {\n            return `Hi, I am ${value}`;\n        },\n    },\n}\n\u003c/script\u003e\n```\n\nThis will display values `Hi, I am John` and `Hi, I am Paul`.\n\n## Adding table footer `\u003ctfoot\u003e` information\n\nSometimes it can be useful to add information to the bottom of the table like summary data.\nA slot named `tfoot` is available and it receives all of the `rows` data to do calculations on the fly or you can show data directly from whatever is available in the parent scope.\n\n```html\n\u003ctable-component\n    :data=\"[{ firstName: 'John', songs: 72 },{ firstName: 'Paul', songs: 70 }]\"\u003e\n    \u003ctable-column show=\"firstName\" label=\"First name\"\u003e\u003c/table-column\u003e\n    \u003ctable-column show=\"songs\" label=\"Songs\" data-type=\"numeric\"\u003e\u003c/table-column\u003e\n    \u003ctemplate slot=\"tfoot\" slot-scope=\"{ rows }\"\u003e\n        \u003ctr\u003e\n            \u003cth\u003eTotal Songs:\u003c/th\u003e\n            \u003cth\u003e{{ rows.reduce((sum, value) =\u003e { return sum + value.data.songs; }, 0) }}\u003c/th\u003e\n            \u003cth\u003e\u0026nbsp;\u003c/th\u003e\n            \u003cth\u003e\u0026nbsp;\u003c/th\u003e\n        \u003c/tr\u003e\n    \u003c/template\u003e\n\u003c/table-component\u003e\n```\n\nOR\n\n```vue\n\u003ctemplate\u003e\n    \u003ctable-component\n        :data=\"tableData\"\u003e\n        \u003ctable-column show=\"firstName\" label=\"First name\"\u003e\u003c/table-column\u003e\n        \u003ctable-column show=\"songs\" label=\"Songs\" data-type=\"numeric\"\u003e\u003c/table-column\u003e\n        \u003ctemplate slot=\"tfoot\"\u003e\n            \u003ctr\u003e\n                \u003cth\u003eTotal Songs:\u003c/th\u003e\n                \u003cth\u003e{{ totalSongs }}\u003c/th\u003e\n            \u003c/tr\u003e\n        \u003c/template\u003e\n    \u003c/table-component\u003e\n\u003c/template\u003e\n\u003cscript\u003e\nexport default {\n    computed: {\n        totalSongs () {\n            return this.tableData.reduce(sum, value =\u003e {\n                return sum + value.songs;\n            }, 0);\n        }\n    },\n    data () {\n        return {\n            tableData: [{ firstName: 'John', songs: 72 },{ firstName: 'Paul', songs: 70 }]\n        }\n    }\n}\n\u003c/script\u003e\n```\n\nNote: `rows` slot scope data includes more information gathered by the Table Component (e.g. `columns`) and `rows.data` is where the original `data` information is located.\n\n## Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.\n\n## Testing\n\n```bash\nyarn test\n```\n\n## Contributing\n\nPlease see [CONTRIBUTING](CONTRIBUTING.md) for details.\n\n## Postcardware\n\nYou're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.\n\nOur address is: Spatie, Samberstraat 69D, 2060 Antwerp, Belgium.\n\nWe publish all received postcards [on our company website](https://spatie.be/en/opensource/postcards).\n\n## Security\n\nIf you discover any security related issues, please contact freek@spatie.be instead of using the issue tracker.\n\n## Credits\n\n- [Freek Van der Herten](https://github.com/freekmurze)\n- [Sebastian De Deyne](https://github.com/sebdedeyne)\n- [All Contributors](../../contributors)\n\nThe Pagination component was inspired by [this lesson on Laracasts.com](https://laracasts.com/series/lets-build-a-forum-with-laravel/episodes/16).\n\n## Support us\n\nSpatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects [on our website](https://spatie.be/opensource).\n\nDoes your business depend on our contributions? Reach out and support us on [Patreon](https://www.patreon.com/spatie).\nAll pledges will be dedicated to allocating workforce on maintenance and new awesome stuff.\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","funding_links":["https://www.patreon.com/spatie"],"categories":["Components","JavaScript"],"sub_categories":["What are scoped slots? :microscope:"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspatie%2Fvue-table-component","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspatie%2Fvue-table-component","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspatie%2Fvue-table-component/lists"}