user2528473
user2528473

Reputation: 321

vuejs: Component for <tr>, how to implement?

After reading docs & forums for hours... still have no answer.

Have the following JS/HTML:

Vue.component("my-component", {
    props: ["id"],
    
    render: function(h) {
        return h("tr", this.$slots.default);
    }
});
    
    
var vapp = new Vue();
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>

<table>
    <tr is="my-component" :name="yo">
        <td>
            <span v-text="name"></span>
        </td>
    </tr>
</table>

Use tr + "is" attribute to specify component within the table otherwise browser will hoist it out as invalid content. Done

Use render + h("tr"...) because vuejs doesn't render tr element, but instead table > td and again browser hoist it out.Done

Now I have table > tr > td rendered well but how can I add children bound to the props/data, so I will see "yo" on the screen.

Thanks a lot!

Upvotes: 10

Views: 14420

Answers (4)

Bert
Bert

Reputation: 82489

If the elements in the slot need access to data inside the component, then you need to use a scoped slot.

Since you are using a render function, the scoped slot is available as a function through this.$scopedSlots.default() and you pass it an object with the data you want to be made available to the scoped slot.

You also need to define the scoped slot in the template. Here is an example.

Vue.component("my-component", {
    props: ["id", "name"],
    
    render: function(h) {
        return h("tr", this.$scopedSlots.default({name: this.name}));
    }
});
    
    
var vapp = new Vue({ el:"#app"});
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>

<div id="app">
<table>
    <tr is="my-component" :name="'yo'">
      <template scope="{name}">
        <td>
            <span v-text="name"></span>
        </td>
      </template>
    </tr>
</table>
</div>

Upvotes: 7

Samuel Aiala Ferreira
Samuel Aiala Ferreira

Reputation: 694

If your're interested in returning multiple rows from your component, you can do like this.

In your main component.

<table width="90%">
    <thead>
    <tr>
        <th width="1%">#</th>
        <th>header description</th>
    </tr>
    </thead>
    <template>
        <your-child-component
                :prop="prop-data"
                v-for="(lancamento, index) in lancamentos"
                :key="lancamento.id">
        </your-child-component
    </template>
</table>

And inside your child component

<template>
    <tbody> <!-- dont forget this tag -->
        <tr>
            <td rowspan="2" v-html="prop.id"></td>
            <td><td>
        </tr>
        <tr>
            <td colspan="2" class="text-center"></td>
        </tr>
    </tbody>
</template>

Upvotes: 0

Adam111p
Adam111p

Reputation: 3727

<table>
    <thead>
        <!-- ...some th -->
    </thead>
    <tbody>
        <tr>
            <td>..</rd>
        </tr>
        <template> <row-component my-param="blabla"></row-component> <!-- component return full row <tr>...</tr>     --> 
        <some-other-recomponent my-par="blabla"></some-other-recomponent> <!-- component return full row <tr>...</tr>    -->
        </template>
    </tbody>
</table>

Upvotes: 1

Nora
Nora

Reputation: 3261

If you are using .vue files you can have the table row component defined like this:

<template>
  <tr>{{ name }}</tr>
</template>

<script>
  export default {
    name: 'table-row',
    props: ['name'],
  };
</script>

Then use it like this:

<table>
  <tr is="TableRow" name="Some name here"></tr>
</table>

Upvotes: 5

Related Questions