Vue 3 transition on table rows

Viewed 539

I'm trying to get a transition (animation) working on an HTML table. I've got it working for a list but not for a table. It works when using vue 2.

My code is adapted from this fiddle.

This is the HTML

<div id="app">
    <div class="row p-2">
        <div class="col-6">
            <h2>List</h2>
            <transition-group class="list-group" name="fruit-list" tag="ul">
                <li class="list-group-item" v-for="item in items" :key="item.id">
                    <div class="d-flex align-items-center">
                        <div>
                            {{ item.name }}
                        </div>
                    </div>
                </li>
            </transition-group>
        </div>
        <div class="col-6">
            <h2>Table</h2>
            <table class="table mb-0">
                <thead>
                <tr>
                    <th scope="col">Fruit</th>
                </tr>
                </thead>
                <tbody name="fruit-table" is="transition-group">
                <tr v-for="item in items" :key="item.id">
                    <th scope="row">{{ item.name }}</th>
                </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

This is the CSS

<style>
    .fruit-list-move {
        transition: transform 1s;
    }
    .fruit-table-move {
        transition: transform 1s;
    }
</style>

This is the javascript

   <script>
        const myapp = {
            data() {
                return {
                    items: [
                        {
                            id: 1,
                            name: "Bananas",
                            quantity: 5
                        }, {
                            id: 2,
                            name: "Apples",
                            quantity: 3
                        }, {
                            id: 4,
                            name: "Oranges",
                            quantity: 1
                        }, {
                            id: 5,
                            name: "Stawberries",
                            quantity: 25
                        },
                    ]
                }
            },

            mounted() {
                this.addItem()
            },

            methods: {
                addItem() {
                    this.items.splice(2, 0, {
                        id: 3,
                        name: "Kiwis",
                        quantity: 8
                    })
                    setTimeout(() => {
                        this.moveItems()
                    }, 2000)
                },
                moveItems() {
                    this.items = this.items.reverse()
                    setTimeout(() => {
                        this.removeItem()
                    }, 2000)
                },
                removeItem() {
                    this.items.splice(2, 1)
                    setTimeout(() => {
                        this.addItem()
                    }, 2000)
                }
            }
        }
        app = Vue.createApp(myapp)
        app.mount('#app')
    </script>

To be honest I am also a little confused about whether Vue 3 is "ready". The homepage still directs to Vue 2 by default.

1 Answers

Hacky hack is here...

<tbody tag="tbody" name="list" is="transition-group">
  <tr v-for="..." :key="...">...</tr>
<tbody>

Example (Warning: writed with pug)

Table have trouble with animation because tr must be in tbody or browser reassembly tree...

To fix that you must transform tbody into transition-group and Vue 3 changed some details.

Related