Vuejs 2 rendering issue with vue router and hot table

Tags: #<Tag:0x00007efc620a90a0> #<Tag:0x00007efc620a8f60>

I’m using handsontable in VueJS 2 single page application. The project uses a bootstrap 4 theme / scss. Vuex & vue router

I have two routes, lets call them Grid1.vue and Grid2.vue that both utilize a hot-table.

If I load Grid1, it renders perfectly as expected. I can navigate to other routes, and come back to Grid1 and it’s great. I can even modify the dataSource for Grid1 by pulling different rows from state, and it works. If I refresh the page, and repeat for process but for Grid2, it works well also. BUT if I navigate from Grid1.vue to Grid2.vue without a page refresh, the hot-table goes haywire.

Column content begins to vanish, and the tbody escapes it’s container… super odd.

Here’s a redacted code snippet

<template>
<div :key="`key_${title}_${key}`"
        v-if="hotSettings.data.length > 0"
        class="w-100"
    >
        <hot-table
            :key="`table_${key}`"
            ref="wrapper"
            :settings="hotSettings"
        >
            <hot-column
                title="Name"
                :width="200"
                :read-only="true"
            >
                <HotColumnUserDetails hot-renderer />
            </hot-column>
            <hot-column
                v-for="day in days"
                :key="`day_${day}`"
                :width="80"
                :title="day"
            >
                <HotCellUserCell
                    hot-renderer
                    hot-editor
                />
            </hot-column>
        </hot-table>
    </div>
</div>
</template>

<script lang="ts">

export default {
    name: 'Grid1',
    components: {...},
    mixins: [...],
    data() {
        return {
            key: 0,
            hotSettings: {
                data: [],
                fixedColumnsStart: 1,
                rowHeaders: true,
                autoRowSize: false,
                autoColumnSize: false,
                rowHeaderWidth: 40,
                rowHeights: 50,
                columnHeaderHeight: 38,
                width: '100%',
                stretchH: 'all',
                licenseKey: 'non-commercial-and-evaluation',
                afterGetRowHeader(col, ele) {
                    const div = ele.firstChild;
                    div.className = 'mt-3';
                },
            },
        };
    },
    computed: {... },
    watch: {
        '$route.extId'() {
            this.populate();
        },
    },
    mounted() {
        this.populate();
    },
    methods: {
        populate() {
            const { data } = this;

            // table header
            const dataSource = [];
            const { assignments } = this;

            // pull some data here, pulling from state
            data.forEach((s) => {
                /// ...
                dataSource.push(row);
            });

            this.hotSettings.data = dataSource;
            this.key += 1;
            
        },
    },
};
</script>

Here’s a screenshot of it without the bug

Grid 1

Grid 2

Once the bug is triggered by going from Grid1 to Grid2 without reloading the browser, this is what happens

The hot-renderer / hot-columns vanish

and scrolling is broken, as the tbody seems to escape it’s container

Thanks for the help!

Hi @jed

I have to say that it might be the first time I see such an issue.

It seems that the cell renderer is broken. Does both of those table share the same function for the cell renderer? Would you be able to replicate the same issue in JSFiddle or Codesandbox?

I had this in the vue file.
Changed it from 80 to 1 and all worked.
Don’t mess with the z-index’s i guess

.handsontable {
  z-index: 80;
}

In Handsontable we have a lot of z-index settings and different for each layer, so yes I wouldn’t change it if not necessary.