Jaroslav KlimĨík Jaroslav KlimĨík - 15 days ago 10
Javascript Question

Vue.js - Component with two rowspan

I'm beginner with Vue.js and I would like to use component. I have a (dynamic) table with machines (SN = serial number) and their money for each source so I want to use rowspan. Each row will be instance of component because has own checkbox and I would like to work with it later. Problem is that I don't know how to use loop with creating component which is a bit complicated inside table. Here is example:

<div id="container">
<table border="1">
<template v-for="row in storage.rows">
<tr>
<td rowspan="2"><input type="checkbox"></td>
<td rowspan="2">{{row.sn}}</td>
<td>{{row.source}}</td>
</tr>
<tr>
<td>{{row.pair.source}}</td>
</tr>
</template>
</table>
</div>

<script>
new Vue({
el: '#container',

data: {
storage: {
rows: [
{sn: 111, source: 'EK', pair: {source: 'VLT', in: 100}},
{sn: 222, source: 'EK', pair: {source: 'VLT', in: 200}}
]
}
},


});
</script>


This works fine but I don't know how to transform template to component. With Vue.js I'm using Laravel and its template engine Blade so I have workaround like this:

<div id="container">
<table border="1">
@foreach($differences as $difference)
<tr is="ek" diff="{{ json_encode($difference) }}"></tr>
<tr is="vlt" diff="{{ json_encode($difference->pair) }}"></tr>
@endforeach
</table>
</div>

<template id="ek-template">
<tr>
<td rowspan="2"><input type="checkbox"></td>
<td rowspan="2">@{{ difference.sn }}</td>
<td>@{{ difference.source }}</td>
</tr>
</template>

<template id="source-template">
<tr>
<td>@{{ difference.source }}</td>
</tr>
</template>

<script>
new Vue({
el: '#container',

data: {
storage: {
differences: {!! json_encode($differences) !!}
}
},

components: {
ek: {
template: '#ek-template',
props: ['diff'],

computed: {
difference: function () {
return JSON.parse(this.diff);
},
},
},

vlt: {
template: '#source-template',
props: ['diff'],
computed: {
difference: function () {
return JSON.parse(this.diff);
},
},
}
},
});
</script>


And I want to use Vue.js loop instead Laravel's
foreach
because I have already data in Vue.js object. Is there any solution how to do it?

Answer

You don't need to mix blade and vue js templates.

Your example is correct, you just need to convert to become a VueJs component for a single file component. (the files *.vue) A vue component structure is

// template should only have one root (e.g. wrap in div)
<template>
    <div id="container">
        <table border="1">
            <template v-for="row in storage.rows">
                <tr>
                    <td rowspan="2"><input type="checkbox"></td>
                    <td rowspan="2">{{row.sn}}</td>
                    <td>{{row.source}}</td>
                </tr>
                <tr>
                    <td>{{row.pair.source}}</td>
                </tr>
            </template>
        </table>
    </div>
</template>


<script>
export default {
    // a data has to be a function within a vue component
    data () {
        return {
            storage: {
                rows: [
                    {sn: 111, source: 'EK', pair: {source: 'VLT', in: 100}},
                    {sn: 222, source: 'EK', pair: {source: 'VLT', in: 200}}
                ]
            }
        }
    }
}
</script>

// styling for a template
<style>
</style>

A new laravel 5.3 project have a sample vue component preinstalled. You can use that as a reference and use gulp to compile all your vue components (*.vue) to a single file (e.g. app.js)