美文网首页
Vue ts - 集成TypeScript

Vue ts - 集成TypeScript

作者: Lisa_Guo | 来源:发表于2019-11-29 13:11 被阅读0次

    TypeScript改变了原生JS弱类型的特性,使得在开发阶段就能尽早防止潜在的运行时错误。TS的类型判断包括JS自带类型(String,Array,Boolean等)及用户自定义类型。
    VUE发布了针对TS的官方类型申明,包含了VUE(https://github.com/vuejs/vue/tree/dev/types)、VUE Router(https://github.com/vuejs/vue-router/tree/dev/types)、Vuex(https://github.com/vuejs/vuex/tree/dev/types)

    1、创建TS的Vue脚手架

    1.1 生成脚手架

    vue create hello-ts
    

    创建时选择支持TypeScript特性


    生成的项目目录结构如下,包含了ts的配置,且js文件替换成了ts文件。

    package.json中可以看到根据用户选择自动引入ts相关的npm包

    1.2 TS支持

    脚手架中shims-vue.d.ts文件做类型申明,让ts能识别vue文件

    declare module '*.vue' {
      import Vue from 'vue'
      export default Vue
    }
    

    shim-jsx.d.tsjsx文件做类型补充说明

    import Vue, { VNode } from 'vue'
    
    declare global {
      namespace JSX {
        // tslint:disable no-empty-interface
        interface Element extends VNode {}
        // tslint:disable no-empty-interface
        interface ElementClass extends Vue {}
        interface IntrinsicElements {
          [elem: string]: any
        }
      }
    }
    

    也可以自定义类型补充来补充vue已经定义好的类型,叫做模块补充 (module augmentation)。可以对vue所有的types进行类型补充

    例如:声明一个string类型的实例属性 $myProperty

    // 1. 确保在声明补充的类型之前导入 'vue'
    import Vue from 'vue'
    
    // 2. 定制一个文件,设置你想要补充的类型
    //    在 types/vue.d.ts 里 Vue 有构造函数类型
    declare module 'vue/types/vue' {
    // 3. 声明为 Vue 补充的东西
      interface Vue {
        $myProperty: string
      }
    }
    

    在项目中可直接和vue自带的其他属性一样使用

    var vm = new Vue()
    console.log(vm.$myProperty) // 将会顺利编译通过
    

    2、TS开发组件

    Component组件为vue最基本的开发单元。要让TS能识别出Vue组件类型,则需要使用Vue.componentVue.extend定义组件

    2.1 基础使用: vue.extend

    vue.extend(options)全局函数可以使用户定义一个vue的子类

    // 加上 lang=ts 让webpack识别此段代码为 typescript
    <script lang="ts">
      import Vue from 'vue'
      export default Vue.extend({
        // ...
      })
    </script>
    

    通过以上方式定义的Component,TS就能够开启类型识别,推断出它的类型

    2.2 基于class: vue-class-component

    vue-class-component官方库提供了componentTS 装饰器,能够像写 class 一样编写组件。点击查看更多

    import Vue from 'vue'
    import Component from 'vue-class-component'
    import Hello from './components/Hello.vue'
    
    // @Component 修饰符注明了此类为一个 Vue 组件
    @Component({
       // 所有的组件选项都可以放在这里
        components: { Hello }
        props: {
            propMessage: String
        },
        watch: {
            propMessage: function(val) {
                this.msg = this.msg + ‘ ’ + val
            }
        }
    })
    export default class App extends Vue {
        // 等价于 data() { return { msg: 'hello' } }
        msg = 'hello';
        
        // 等价于是 computed: { computedMsg() {} }
        get computedMsg(): string {
            return 'computed ' + this.msg
        }
        
        // 等价于 methods: { greet() {} }
        greet() : void {
            console.log(this.computedMsg())
        }
    
        // lifecycle hook
        mounted () : void {
          this.greet()
       }
    }
    

    class-style的组件开发方式:

    • methods: 声明为类函数。如上例中的greet()
    • computed属性: 声明为get 类属性访问器。如上例中的computedMsg()
    • data: 声明为类属性。如上例中msg
    • vue methods: vue的 data/render/生命周期函数,都可以申明为类函数。如上例中的mounted
    • 其他vue的options: 其他vue options,如 components,props,watch等,放在component装饰器里(所有vue options原则上都可以放在此处),写法保持原来的vue options写法。如上例的props

    2.3 扩展装饰器

    vue-property-decorator是个非官方库,在 vue-class-component 上增强更多的结合 Vue 特性的装饰。为原本需要放在@components里的options(components,props,watch等)提供装饰器。点击查看更多

    vue-property-decorator也提供了vue-class-component的功能,文件中只引入这一个包即可。但安装依赖时要安装vue-class-component

    上面的例子就改为

    import { Vue, Component, Prop, Watch } from 'vue-property-decorator'
    import Hello from './components/Hello.vue'
    
    // @Component 修饰符注明了此类为一个 Vue 组件
    @Component({
        components: { Hello }
    })
    export default class App extends Vue {
        @Prop()  private proMessage!: String
        @Watch('msg')
        onMsgChanged(val: string, oldVal: string) {
            this.msg = this.msg + ‘ ’ + val
        }
    
        // 等价于 data() { return { msg: 'hello' } }
        msg = 'hello';
        
        // 等价于是 computed: { computedMsg() {} }
        get computedMsg(): string {
            return 'computed ' + this.msg
        }
        
        // 等价于 methods: { greet() {} }
        greet() : void {
            console.log(this.computedMsg())
        }
    
        // lifecycle hook
        mounted () : void {
          this.greet()
       }
    }
    

    参考文章

    1. https://www.cnblogs.com/foxcharon/p/10951227.html
    2. https://www.jianshu.com/p/9eca70b033da

    相关文章

      网友评论

          本文标题:Vue ts - 集成TypeScript

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