fengyuanchen / vue-countdown

Countdown component for Vue.js.
https://fengyuanchen.github.io/vue-countdown/
MIT License
691 stars 89 forks source link

The render function crashes when using @vue/compat. #94

Closed ianef closed 7 months ago

ianef commented 7 months ago

I'm migrating a project to Vue 3 that requires the use of @vue/compat until some other depencencies can be resolved or replaced.

I've replaced another component with vue-countdown, this has a much closer fit to what we need, however it's crashing in the render function.

                <vue-countdown :time="refreshMilliseconds" v-slot="{ hours, minutes, seconds }" @end="onReloadWindow">
                    Auto refresh in {{ hours }} hours, {{ minutes }} minutes, {{ seconds }} seconds
                </vue-countdown>
error-service.js:46 TypeError: Cannot destructure property 'hours' of 'undefined' as it is undefined.
    at tcp-index.vue:34:44
    at renderFnWithContext (vue.esm-bundler.js:2896:1)
    at Object.get (vue.esm-bundler.js:5295:1)
    at Proxy.render (vue-countdown.esm.js:361:17)
    at Proxy.compatRender (vue.esm-bundler.js:5099:1)
    at renderComponentRoot (vue.esm-bundler.js:2959:1)
    at ReactiveEffect.componentUpdateFn [as fn] (vue.esm-bundler.js:9348:1)
    at ReactiveEffect.run (vue.esm-bundler.js:535:1)
    at instance.update (vue.esm-bundler.js:9407:1)
    at updateComponent (vue.esm-bundler.js:9192:1)

The problem is that this.$slots.default is not accessible, there are a few other posts around relating to this where @vue/compat is used.

I've locally copied index.ts to debug it and found that by including compatConfig: { RENDER_FUNCTION: false } resolves the problem:

...
const index = defineComponent({
    name: 'VueCountdown',
    compatConfig: { RENDER_FUNCTION: false },
    props: {
'''

I don't think adding a compatConfig property when @vue/compat is not used would cause a problem, I'm not sure as I haven't had the time to setup another project to test that, but would you consider adding this change to resolve this problem.

It's also worth noting that components that rendered via a \<template> tag apparently do not have this issue.

fengyuanchen commented 7 months ago

You can add the compatConfig property directly before installing the component:

import VueCountdown from '@chenfengyuan/vue-countdown';

VueCountdown.compatConfig = { RENDER_FUNCTION: false };
// ...
ianef commented 7 months ago

Excellent, thanks for that @fengyuanchen.