2

Vue+TypeScript使用小结

  1. 创建新工程,可以安装vue cli 3,通过vue create创建

    npm install --global @vue/cli
  2. 必须 添加vue文件声明shims-vue.d.ts, 用于TypeScript识别vue文件。内容可参考下例。
    1) ts默认不支持导入vue文件, 需要通过以下声明语句告诉ts按VueConstructor <Vue> 处理vue文件的导入。因此,引用vue文件必须加上.vue后缀。
    2) 当我们需要在Vue上挂载全局变量或方法时,
    e.g. Vue.prototype.$ajax=axios;
    需要在Vue接口上声明相应变量

    import Vue from 'vue'
    import { AxiosInstance } from 'axios';
    
    declare module 'vue/types/vue' {
        interface Vue {
            $ajax: AxiosInstance;
            _: any;
            $util: any;
        }
    }
    
    declare module '*.vue' {
        export default Vue
    }
  3. 非必须 添加shims-tsx.d.ts文件,可以方便在ts中使用jsx语法。使用jsx语法和使用我们使用模板编写的方式主要区别在于,使用模板无法获得静态类型提示。配合babel-plugin-jsx-v-model插件可以在jsx语法中实现v-model
  4. 使用TypeScript编写Vue的时候,主要有两种方法:Vue.extend()和vue-class-component,两种方法对script部分添加属性lang=ts
    1) Vue.extend():使用基础vue构造器,创建一个子类,接近我们以前的vue写法。用Vue.extend()包裹组件内容就可以了。通过Vue.extend定义组件可以启用vue的类型推断,类似下例:

    <script lang="ts">
    import Vue from'vue';
    export default Vue.extend({
        name:'MyComponent',
    });
    </script\>

    2) vue-class-component: vue官方维护的装饰器,通过各种修饰符进行注明,可以结合vue-property-decorator进行使用

    <script lang="ts">
    import Vue from 'vue'
    import Component from'vue-class-component'
        // @Component修饰符注明了此类为一个Vue组件
        @Component({
            template:'<button @click="onClick">Click!</button>'
        })
    
    export default class MyComponent extends Vue{
        //初始数据可以直接声明为实例的属性
        message:string\='Hello!'
        //组件方法也可以直接声明为实例的方法
        onClick():void{
            window.alert(this.message)
        }
    }
    </script\>
  5. prop类型定义:
    1) 对于Array、Object

      mylist:  Array, //错误的❌。
      mylist:  Array as () => Array<any>, //正确的写法✅
    

    2) props内类型定义的错误会影响后续对props和data中定义的字段的引用,出现类似“Property 'xxx' does not exist on type 'Vue'.”错误。

  6. vuex使用,
    1) 参考文章

       i. [https://juejin.im/post/5c46c625e51d456e4138fa82](https://juejin.im/post/5c46c625e51d456e4138fa82)
       ii.[https://segmentfault.com/a/1190000011864013](https://segmentfault.com/a/1190000011864013)
    

    2)不建议使用mapState/mapGetters/mapActions/mapMutations,以明确指定类型。但是store中的类型还是会丢失.

    computed:{
        tags():Array<article.Tag> {
            returnthis.$store.state.tags;
        },
    },
  7. eslint:
    1) 基础的typescript eslint配置

    extends:\['@vue/typescript'\],
    rules:{
        // typescript-eslint rules
        '@typescript-eslint/indent':\['error',4\],
        '@typescript-eslint/explicit-function-return-type':0
    },
    parserOptions:{
        parser:'@typescript-eslint/parser'
    },

    2) 如果遇到lint报错:

    eslint typescript type is defined but never used。

    增加如下lint配置

    overrides:[
        {
            files:['*.ts','*.tsx','*.vue'],
            rules:{
                '@typescript-eslint/no-unused-vars':[2, {args:'none'}]
            }
        }
    ]
  8. 编译:使用命令vue add typescript,编译时会增加typescript编译。

    vue add typescript
    等同于 npm i -D @vue/cli-plugin-typescript

    不需要我们去设定 webpack loader。vue 自己会处理 ts

  9. vscode:
    1) 在vue文件内的ts使用声明的全局namespace。vscode会提示cannot find namespace;但是实际上编译没问题,ts对于声明type的校验也没问题。暂时只能忽略,没有找到好的解决方法。
  10. 其他:
    1) webpack alias设置
    vue.config.js 增加配置

    const path = require("path");
    const resolve = dir => path.resolve(__dirname, dir);
    module.exports = {
        chainWebpack: config => {
            config.resolve.alias.set("@", resolve(src));
            return config;
        }
    }

    tsconfig.json 增加配置

    {
        "compilerOptions": {
            "paths": {
                "@/*": ["src/*"]
            }
        }
    }

    配置完成后重启 vscode 生效

  11. 一些报错处理:
    1)Module 'lodash can only be default-imported using the 'allowSyntheticDefaultImports' flagts(1259)
    解决方案: tsconfig增加配置

    "allowSyntheticDefaultImports": true

spoonysnail
80 声望1 粉丝