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

11,953

Solution 1

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>

Solution 2

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>

Solution 3

<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>
Share:
11,953

Related videos on Youtube

user2528473
Author by

user2528473

Updated on September 15, 2022

Comments

  • user2528473
    user2528473 over 1 year

    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!

  • user2528473
    user2528473 over 6 years
    The example above works. Thanks a lot! Are these props, within the scoped slot, reactive? Did some example, seems like are not.
  • user2528473
    user2528473 over 6 years
    I want to render HTML on server side and have vuejs component to enrich that table row with some functionality.
  • user2528473
    user2528473 over 6 years
    What about methods? May I supply event handlers to the scoped slot? P.S. Seems like vuejs forces me to work in data driven mode. But all I want is to enrich rendered, on server side, HTML.
  • Bert
    Bert over 6 years
    @user2528473 What is passed will be reactive if you pass an observed property. In the example above, the prop is just a string, so it isn't. If a data property was passed it would be. You can pass functions through the scoped slot if you want, just add them to the object passed as the argument. It's true, Vue is a data driven library. The rendered DOM is intended to be a reflection of state.