Typescript在Vue项目中的使用

最近尝试了一下Typescript在Vue项目中的使用,中间遇到了一些问题,把遇到的问题记录一下,以防被忘。

如何让Typescript识别Vue、JSON文件

因为Typescript默认不能识别.vue文件,导致在引用.vue文件时,提示加载错误。所以需要自己新建一个 .d.ts 文件添加以下内容。这告诉Typescript以.Vue结尾的导入的任何东西都与Vue构造函数本身具有相同的形状。

// *.d.ts
declare module "*.vue" {
  import Vue from "vue";
  export default Vue;
}
复制代码

另外在项目中难免会使用到一些 .json 配置文件,在引用时同样因为Typescript不能识别,同样也需要自己在 *.d.ts 文件声明。

// .d.ts
declare module "*.json" {
  const value: any;
  export default value;
}
复制代码

需要注意的时,这些 .d.ts 文件不能放到项目运行入口文件上级目录,否则Typescript没找到这些声明,导致不能正确识别文件类型。

使用装饰器定义组件

在Vue项目中使用Typescript,定义.vue文件一般使用类似React的Class 形式,所以这里只记录一下在 Class 这种形式的写法。使用这种方式需要使用装饰器来定义组件,这需要额外的两个包 vue-class-componentvue-property-decorator,其中vue-property-decorator依赖vue-class-component。这2个包可以让我们使用装饰器来定义组件的方法、属性、watch等内容。

在vue-class-decorator中提供了@Emit、@Inject、Mixins、@Model、@Prop、@Provide、@Watch、@Component,8种装饰器,具体使用方法这里不做过多介绍,具体请看这里。其中Mixins、@Component继承于vue-class-component。

Computed、Data、Methods

这里取消了组件的data和methods属性,以往data返回对象中的属性、methods中的方法需要直接定义在Class中,当做类的属性和方法。

@Component
export default class HelloDecorator extends Vue {
    count: number = 123

    increment() {
      // xxxx
    }
}
复制代码

Computed在这里也被取消,变成了带有get和set的类方法。

@Component
export default class HelloDecorator extends Vue {
    count: number = 123

    // 获取计算属性
    get total(): number {
      return this.count + 1
    }

    // 设置计算属性
    set total(param:number): void {
      this.count = param
    }
}
复制代码

@Component(继承自vue-class-component)

Component装饰器它注明了此类为一个Vue组件,因此即使没有设置选项也不能省略。如果需要定义比如 name、components、filters、directives以及自定义属性,就可以在Component装饰器中定义。

@Component({
  name: 'xComponent',
  pageName: 'page title', // 自定义属性
  components: {
    // xxxx
  },
  filters: {
    // xxxx
  },
  directives: {
    // xxxx
  }
})
export default class HelloDecorator extends Vue {
}
复制代码

关于组件名,如果不设置name属性,组件名将使用类名。优先级: name > 类名。

在上面我们还定义组件的自定义属性,但Vue并没有提供对自定义属性的声明支持,所以在定义自定义属性时,需要我们在.d.ts文件中扩展ComponentOptions,声明我们自己定义的属性。

declare module 'vue/types/options' {
  interface ComponentOptions<V extends Vue> {
    // 自定义的属性
    pageName?: string;
  }
}
复制代码

@Prop

在使用Prop装饰器定义属性时,如果我们打开了tsconfig.js 配置文件中的 strictpropertyinitialize 选项,我们就需要通过附加一个!给定义的属性。这就告诉TypeScript:“嘿,放松,其他人会给这个属性赋值”。如果不这样做的话,TypeScript会告诉你: “嘿,注意,这个属性你还没初始化”。需要注意的是: 给属性设置default值,并不是上面的初始化。 ! 它在延迟初始化或重新初始化的场景下很方便使用。

@Component
export default class YourComponent extends Vue {
  @Prop(Number) propA!: number
  @Prop({ default: 'default value' }) propB!: string
  @Prop([String, Boolean]) propC: string | boolean
}
复制代码

上面的问题同样适用于 @Inject、@Model装饰器。

// @Inject
@Component
export class MyComponent extends Vue {
  @Inject() foo!: string
  @Inject('bar') bar!: string

  @Provide() foo = 'foo'
  @Provide('bar') baz = 'bar'
}

// @Model
@Component
export default class YourComponent extends Vue {
  @Model('change', { type: Boolean }) checked!: boolean
}
复制代码

$refs的使用

我们经常给元素或组件添加ref属性,以便对元素操作和访问组件的属性和方法。但在这里当我们需要使用$refs时,需要提前声明refs内容的类型,以便Typescript能做出正确的类型判断。

<div ref="div"></div>

<e-component ref="cComponent"></e-componen>
复制代码
import eComponent form 'xxxx'

@Component({
  components: {
    'e-component': eComponent
  }
})
export default class YourComponent extends Vue {
  // 注意这里的感叹号
  $refs!: {
    div: HTMLDivElement, // html元素
    cComponent: eComponent // Typescript可以正确提示出组件中的方法和属性
  }
}
复制代码

Vuex-class

Vuex-class是把Vuex和vue-class-component绑定到一起的一个包。目前还没有遇到问题,也就不做详解了。具体使用方式请查看文档

上面就是目前在Vue项目中使用Typescript遇到的问题和注意点,其它问题待后续遇到后加以补充。

转载于:https://juejin.im/post/5b8c9e23f265da433207332d

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值