记录Vue3+TS展示json动图的坑

1,456 阅读1分钟

展示json动图我用的库是lottie-web

npm i lottie-web --save

Vue3使用ref获取dom节点是这样的

let animation = ref<null | HTMLElement>(null)

然后我就愉快的开始使用

let animation = ref<null | HTMLElement>(null)
onMounted(() => {
    console.log(animation.value) //div
    
    lottie.loadAnimation({
        container: animation.value,
        renderer: 'svg',
        loop: true,
        autoplay: true,
        animationData: shalouJson,
    })
})

然后报错了
Type 'null' is not assignable to type 'Element'.

我看了下源码 发现lottie-web的container必须是Element,但是这个时候dom其实是挂载好了的,只是Vue3通过ref绑定节点的时候一开始是null 应该是TS的类型检测报的错误。

export type AnimationConfig<T extends 'svg' | 'canvas' | 'html' = 'svg'> = {
    container: Element; //这里只支持Element
    renderer?: T;
    loop?: boolean | number;
    autoplay?: boolean;
    initialSegment?: AnimationSegment;
    name?: string;
    assetsPath?: string;
    rendererSettings?: {
        svg: SVGRendererConfig;
        canvas: CanvasRendererConfig;
        html: HTMLRendererConfig;
    }[T]
}

最终我的解决方案 加个if判断

<template>
    <div ref="animation"></div>
</template>

<script lang="ts">
import lottie from 'lottie-web'
import shalouJson from '@/assets/json/shalou.json'
import { defineComponent, onMounted, ref } from 'vue'

export default defineComponent({
    name: 'jsonImg',
    setup() {
        let animation = ref<null | HTMLElement>(null)
        onMounted(() => {
            if (animation.value) {
                lottie.loadAnimation({
                    container: animation.value,
                    renderer: 'svg',
                    loop: true,
                    autoplay: true,
                    animationData: shalouJson,
                })
            }
        })
        return {
            animation,
        }
    },
})
</script>

<style lang="scss" scoped></style>