Vue ts - 集成TypeScript

2019-11-29  本文已影响0人  Lisa_Guo

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的组件开发方式:

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
上一篇下一篇

猜你喜欢

热点阅读