Reputation: 1368
I am working on a Vue single file component that shows a table based on JSON object. I want to run a filter dynamically to allow each column to have it's own filters.
Inside the <td>
v-for
loop I want to check row.filter
variable and either call the filter accordingly or not when it is undefined. My current code, however, will crash the component.
<template>
<table>
<thead>
<tr>
<th v-for="(row, rowNumber) in tableRows" v-bind:key="rowNumber">
{{ row.header }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="model in list" v-bind:key="model.id">
<td v-for="(row, rowNumber) in tableRows" v-bind:key="rowNumber">
<!--
the following will crash the component
-->
{{ model[row.property] | row.filter }}
</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
data: () => ({
tableRows: [{
header : 'ID',
property: 'id'
},{
header : 'User',
property: 'name'
},{
header : 'E-mail',
property: 'email'
},{
header : 'Created at',
property: 'created_at',
filter : 'formatDate' // the only column with filter
}],
list: [{
id : 1,
name : "Admin User",
email : "[email protected]",
description: "Sample admin",
created_at : "2020-07-05 13:12:35"
}]
}),
filters: {
formatDate (date) {
date = new Date(date);
return date.toLocaleString()
}
}
}
</script>
Upvotes: 1
Views: 254
Reputation: 6853
You can use v-if
v-else
<template v-if="row.filter">{{ model[row.property] | formatDate() }}</template>
<template v-else>{{ model[row.property] }}</template>
Since you want to avoid using v-if
and filter is going to be deprecated in Vue 3 anyway, here's what you can do instead:
methods: {
// format handler
format (value, filter) {
if (filter === "formatDate") return this.formatDate(value);
if (filter === "otherFormat") return this.otherFormat(value);
return value;
// or call function name dynamically
if (filter) return this[filter](value);
return value;
},
// all filters will be moved to methods
formatDate (date) {
return new Date(date).toLocaleString();
}
otherFormat (value) {
return someOtherFormat(value);
}
}
<tr v-for="model in list" v-bind:key="model.id">
<td v-for="(row, rowNumber) in tableRows" v-bind:key="rowNumber">
{{ format(model[row.property], row.filter) }}
</td>
</tr>
Upvotes: 1