“可复用的过渡”改写成函数式组件

我学习到 Vue3 文档 “可复用的过渡” 一节(https://v3.cn.vuejs.org/guide...),把更前一点的例子改写成了过渡组件(如下),但是根据文档,说可以改写成函数式组件,但我改了不成功啊 (注:我是用自行托管方式使用 Vue 的,即 <script>导入vue.global.js)

<html>

<head>
    <script src="https://unpkg.com/vue@3.2.26/dist/vue.global.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/gsap.min.js"></script>
</head>

<body>
    <div id="app">
        <input v-model="query" />
        <my-transition-group>
            <li v-for="(item, index) in computedList" :key="item.msg" :data-index="index">
                {{ item.msg }}
            </li>
        </my-transition-group>
    </div>
    <script>
        const { createApp } = Vue
        const app = createApp({
            data() {
                return {
                    query: '',
                    list: [
                        { msg: '张三' },
                        { msg: '李四' },
                        { msg: '王五' },
                        { msg: '李六' },
                        { msg: '张七' }
                    ]
                }
            },
            computed: {
                computedList() {
                    var vm = this
                    return this.list.filter(item => {
                        return item.msg.indexOf(vm.query) !== -1
                    })
                }
            },
        })
        app.component('my-transition-group', {
            template: '\
            <transition-group\
                name="staggered-fade"\
                tag="ul"\
                :css="false"\
                @before-enter="beforeEnter"\
                @enter="enter"\
                @leave="leave"\
            >\
                <slot></slot>\
            </transition-group>\
            ',
            methods: {
                beforeEnter(el) {
                    el.style.opacity = 0
                    el.style.height = 0
                },
                enter(el, done) {
                    gsap.to(el, {
                        opacity: 1,
                        height: '1.6em',
                        delay: el.dataset.index * 0.15,
                        onComplete: done
                    })
                },
                leave(el, done) {
                    gsap.to(el, {
                        opacity: 0, 
                        height: 0,
                        delay: el.dataset.index * 0.15,
                        onComplete: done
                    })
                }
            }
        })
        const vm = app.mount('#app')
    </script>
</body>

</html>

我改写的如下 (Uncaught TypeError: createElement is not a function)

<html>

<head>
    <script src="https://unpkg.com/vue@3.2.26/dist/vue.global.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/gsap.min.js"></script>
</head>

<body>
    <div id="app">
        <input v-model="query" />
        <my-transition-group>
            <li v-for="(item, index) in computedList" :key="item.msg" :data-index="index">
                {{ item.msg }}
            </li>
        </my-transition-group>
    </div>
    <script>
        const { createApp } = Vue
        const app = createApp({
            data() {
                return {
                    query: '',
                    list: [
                        { msg: '张三' },
                        { msg: '李四' },
                        { msg: '王五' },
                        { msg: '李六' },
                        { msg: '张七' }
                    ]
                }
            },
            computed: {
                computedList() {
                    var vm = this
                    return this.list.filter(item => {
                        return item.msg.indexOf(vm.query) !== -1
                    })
                }
            },
        })
        app.component('my-transition-group', {
            functional: true,
            render: function (createElement, context) {
                var data = {
                    props: {
                        name: 'staggered-fade',
                        tag: 'ul',
                        css: false,
                    },
                    on: {
                        beforeEnter(el) {
                            el.style.opacity = 0
                            el.style.height = 0
                        },
                        enter(el, done) {
                            gsap.to(el, {
                                opacity: 1,
                                height: '1.6em',
                                delay: el.dataset.index * 0.15,
                                onComplete: done
                            })
                        },
                        leave(el, done) {
                            gsap.to(el, {
                                opacity: 0,
                                height: 0,
                                delay: el.dataset.index * 0.15,
                                onComplete: done
                            })
                        }
                    }
                }
                return createElement('transition-group', data, context.children)
            }
        })
        const vm = app.mount('#app')
    </script>
</body>

</html>
阅读 1.6k
1 个回答
  • createElement 问题参考link,这里Vue3语法改了
  • 插槽问题参考link
h('transition-group', data, this.$slots.default())
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题