使用 TypeScript 编写 Vue 单文件组件:vue-class-component 或者 Vue.extend

Vue.js

如果你想要在 Vue 中使用 Typescript,那么你首先需要确保你的 Vue 文件是类型安全的。

只需要将 lang="ts" 添加到你的 .vue 文件的脚本标识中,但像往常一般编写可直接运行的正常组件,那么或许你将错过 90% 由 Typescript 所提供的工具支持。

本文将介绍两种用 Typescript 编写 Vue 组件的推荐方法,两者都是在 Vue 文档中支持的。supported in the Vue documentation.

vue-class-component( Vue 类组件)

vue-class-component 是一个 ES / Typescript 修饰符,可以为用户提供编写 类风格 Vue 组件的能力。它通常与 vue-property-decorator 一起来使用。

以下是使用 vue-class-component 编写的组件示例:

<script lang="ts">
import Component from "vue-class-component"
import { Prop } from "vue-property-decorator"
type ComplexObjectInterface = {
  testProp: string
  modelName: number
}
@Component
export default ComponentName extends Component {
  @Prop({
    type: Object
  })
  propExample: ComplexObjectInterface

  dataExample: string = "This Property Will Be Data"

  get computedExample() {
    return this.dataExample + this.propExample.testProp + "Computed Property Example";
  }

  methodExample() {
    this.dataExample = "This is being done in a method"
  }
}
</script>

该类按照如下所示的规则蓝图,映射到 Vue 组件中:

  • 组件数据 → 在类中定义和实例化的任意属性
  • 计算属性 → getters
  • 组件方法 → 在类中定义的任意方法
  • 组件属性 → 使用 @prop() 装饰器定义属性或作为 @component 装饰器的参数( 示例在此

直到最近,这一直是确保 Vue 组件类型安全的唯一方法。

Vue.extend()

最新版的 Vue 重构了部分 TypeScript 代码,所以我们有了一种新的使用 TypeScript 编写 Vue 组件的方式:Vue.extend

我称之为 经典方法,因为这与标准 Vue 组件从字面上看完全相同,不过它必须显示的包装在 Vue.extend 中。

基于最新的变更及类型推断,TypeScript 编译器目前可以根据对象结构和在 Vue.extend() 中的参数,自动为 Vue 组件提供类型支持。

<script lang="ts">
import Vue, { PropTypes } from "vue"
type ComplexObjectInterface = {
  testProp: string
  modelName: number
}
export default Vue.extend({
  props: {
    propExample: {
      // 注:此功能尚不存在
      // 查看如下 github 分支获取更多信息
      // https://github.com/vuejs/vue/pull/6856 
      type: Object as PropTypes<ComplexObjectInterface>
    }
  },
  data() {
    return {
      dataExample: "This Property Will Be Data"
    }
  },
  computed: {
    computedExample(): string {
      return (
        this.dataExample +
        this.propExample.testProp +
        "Computed Property Example"
      )
    }
  },
  methods: {
    methodExample() {
      this.dataExample = "This is being done in a method"
    }
  }
})
</script>

这与 vue-class-components(Vue 类组件)一个重要区别的是,它是基本的 Object(对象) 而不是 Class(类)。

此外,由于这是定义 Vue 组件的经典方式,所以基本所有的 Vue 工具都能做到开箱即用 (如 Vetur )。

Vue.js

Vetur 可以对组件定义智能感知。

哪一种方式更优?

特性 vue-class-component Vue.extend
自动识别组件中的 Prop x
Props 类型安全 x
Data 类型安全
Computed 属性类型安全
Methods 类型安全

当你阅读到这里的时候请注意,这些只是风格差异,实际上它们可以做完全相同的事。

对于我个人而言,我更喜欢 Vue.extend 这样的方式,因为我相信它更容易讲授和理解。从风格上来说,它更像是把 Typescript 放进了 Vue 之中,而不是把 Vue 强行添加到 Typescript 之中。

额外的抽象层不值得这么方便,特别是对于typed-props即将推出。

如果您有需要自定义键入的复杂属性(props),那么vue类组件可能更有意义。在当前版本中,不能使用Vue.扩展来隐式地将属性(props)转换为类/接口.

目前,这两项都包含在官方文件中,因此这两项都将得到支持。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://frontendsociety.com/writing-sing...

译文地址:https://learnku.com/vuejs/t/53869

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!