美文网首页前端开发那些事儿
vue3+typescript实战记录一

vue3+typescript实战记录一

作者: 俄小发 | 来源:发表于2020-12-28 16:01 被阅读0次

    本文记录一些vue3+ts+less开发过程中的一些小问题。
    不断开发、不断更新...

    1. 引用.vue文件报错(vue3必须使用.vue后缀?暂时没找到解决方案)

    问题

    新建Hello.vue文件,App.vue文件引入Hello.vue,报错如下:
    没有发现模块components/Hello或者它对应的类型申明

    image.png

    解决方案(vue2的解决方案)

    参考链接:https://stackoverflow.com/questions/64213461/vuejs-typescript-cannot-find-module-components-navigation-or-its-correspon

    2. .vue文件export导出

    要让 TypeScript正确推断 Vue 组件选项中的类型,需要使用 defineComponent 全局方法定义组件。
    参考文档

    import {defineComponent} from 'vue';
    export default defineComponent({
    // 开启类型推断
    });
    

    3. 引入第三方库

    引用第三方库时,如果第三方类库并没有ts.d.ts类型的声明文件,则无法在项目中正常使用。如果要顺利使用这些库, 就需要我们添加声明文件。

    通过此地址可以查找当前安装的库有没有.d.ts的声明文件。

    项目中引入echarts

    npm install echarts --save
    import * as echarts from 'echarts';
    echarts.init(dom); // 正常使用
    

    ts声明查找地址发现echarts已经包含.d.ts类型的声明文件,则不需要我们手动去声明echarts模块

    image.png

    4. 定义对象类型变量

    看了基础类型模块,想当然以为定义对象类型为下面示例:

    let option: object = {
         title: {
             text: 'ECharts 入门示例'
         },
         legend: {
            data: ['销量']
         },
         xAxis: {
            data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
         },
         yAxis: {},
         series: [{
             name: '销量',
             type: 'bar',
             data: [5, 20, 36, 10, 10, 20]
         }]
    };
    

    报错如下:
    提示不能使用object作为类型。推荐考虑使用Record<string, unknown>代替。

    image.png

    解决方案

    1. 使用Record<string, any>(检查不够严格)

    参考文档

    let option: Record<string, any> = {
        ....
    }
    

    2. 使用interface接口定义类型(每一个属性检查严格)

    参考文档

    // 定义echarts options接口interface
    interface echartsOptions {
        // 非必须属性,key为string,value为any类型
        title?: Record<string, any>;
        legend?: Record<string, any>;
        // 非必须属性,值为string类型组成的数组
        color?: string[];
        xAxis: Record<string, any>;
        yAxis: Record<string, any>;
        series: Record<string, any>;
        // 接收指定属性之外的额外属性,不会报bug
        [propName: string]: any
    }
    let option: echartsOptions = {
        ....
    }
    

    5. ref或document获取dom元素

    <template>
        <div id="main" ref="echarts1" style="width: 600px;height:400px;"></div>
        <div id="main2" ref="echarts2" style="width: 600px;height:400px;"></div>
    </template>
    

    解决方案

    (1)通过document获取dom元素

    通过as HTMLElement进行类型转换

    let myChart = echarts.init(document.getElementById('main') as HTMLElement);
    

    (2)setup中通过ref获取dom元素

    setup中定义的变量和方法,都必须通过return {}暴露出去,外界才能使用,ref函数仅能监听基本类型的变化,不能监听复杂类型的变化(比如对象、数组)
    setup里获取ref绑定的dom,需要在setupreturnref(null)的属性,模板上ref用对应属性名

    import {ref} from 'vue';
    setup() {
        // <>类型声明
        const echarts1 = ref<HTMLElement|null>(null);
        const echarts2 = ref<HTMLElement|null>(null);
        let myChart = echarts.init(echarts1.value as HTMLElement);
        return {
            echarts1,
            echarts2
        };
    }
    

    (3)mounted中通过$refs获取dom元素

    通过this.$refs去获取

    mounted() {
        let myChart = echarts.init(this.$refs.echarts2 as HTMLElement);
    }
    

    6. 获取挂载在window对象上的属性a报错

    image.png

    解决方案

    (1)使用类型断言

    缺点:在 any 类型的变量上,访问任何属性都是允许的。它极有可能掩盖了真正的类型错误,所以如果不是非常确定,就不要使用 as any。

    (window as any).a = 1;
    

    (2)类型申明

    src根目录*.d.ts文件中进行类型申明

    interface Window {
        a: any;
    }
    

    相关文章

      网友评论

        本文标题:vue3+typescript实战记录一

        本文链接:https://www.haomeiwen.com/subject/ymaynktx.html