Pass props / parameters to custom component field?
I have data being returned from my API in the following format:
{
"total": 1000,
"per_page": 5,
"current_page": 1,
"last_page": 200,
"next_page_url": "....",
"prev_page_url": null,
"from": 1,
"to": 5,
"data": [
{
"order_number": 1,
"departments": ["manufacturing", "packaging", "shipping"]
},
{
"order_number": 2,
"departments": ["manufacturing", "shipping"]
},
{
"order_number": 3,
"departments": ["packaging", "shipping"]
},
{
"order_number": 4,
"departments": ["shipping"]
},
{
"order_number": 5,
"departments": ["manufacturing"]
}
]
}
For each order, there's a list of departments. I wish to display the following using VueTable:
+---------+---------------+-----------+----------+
| Order # | Manufacturing | Packaging | Shipping |
+---------+---------------+-----------+----------+
| 1 | true | true | true |
+---------+---------------+-----------+----------+
| 2 | true | false | true |
+---------+---------------+-----------+----------+
| 3 | false | true | true |
+---------+---------------+-----------+----------+
| 4 | false | false | true |
+---------+---------------+-----------+----------+
| 5 | true | false | false |
+---------+---------------+-----------+----------+
To make matters more confusing, this list of departments (and therefore fields to be displayed) is subject to change.
Worst-case scenario I can find a work-around by changing my API output to include "hasXXX" fields, however I would prefer to define my table with something like the following:
<template>
<vuetable :fields="fields" api-url="..."></vuetable>
</template>
<script>
export default {
data: function() {
var fields = allPossibleDepartments.map(dep => { // Populated via API or otherwise
return {
name: '__component:has-department(' + dep + ')',
title: dep
};
});
return { fields: fields };
}
};
</script>
I could then create a single has-department component with a dep prop which tells it which department to search for.
There may be an easier way to accomplish this that I just haven't thought of yet, but regardless I think there's value in being able to pass props to custom components.
@stevendesu Maybe you can try using __slot (scoped slot).
The following code might give you an idea, but I haven't tested it so I'm not sure.
<template>
<vuetable ref="vuetable"
:fields="fields" api-url="..."
>
<template v-for="dep in allPossibleDepartments" :slot="dep" scope="props">
{{ props.departments.indexOf(dep) > 0 ? 'true' : 'false' }}
</template>
</vuetable>
</template>
<script>
var fieldsDef = []
fieldsDef.push({
name: 'order',
title: 'Order #'
})
fieldsDef.push(
allPossibleDepartments.map(dep => {
return {
name: '__slot:' + dep,
title: dep
}
})
)
export default {
data () {
return {
fields: fieldsDef
}
}
}
</script>
@ratiw When I'm home tonight I'll try this out and see if it works.
@ratiw It took a lot of experimentation (stripping away pieces bit by bit to get a minimum test case then making several variations on that test case) but I figured it out
Replace:
<template v-for="dep in allPossibleDepartments" :slot="dep" scope="props">
With:
<div v-for="dep in allPossibleDepartments" :slot="dep" scope="props">
The <template> element apparently does not support property binding. You can use <template> with static properties, but using :slot sets the "slot" property to null (and thus the component is never loaded)
Update: Scratch that... while changing it from <template> to <div> fixed the issue of a dynamic "slot" property, it broke the "scope" property. I wasn't able to access the row data. I guess this is just a limitation of VueJS at the moment
Update 2: I've created the following bug report for VueJS: https://github.com/vuejs/vue/issues/4951