Vue2项目中引入TypeScript的一些用法

600 阅读1分钟

前言

最近项目中引入了TypeScript,这里针对一些用法做一些简单的记录。

安装

项目中引入了vue-property-decorator

npm i -S vue-property-decorator // 下面的示例,使用的版本为:^9.0.2

vue-property-decorator是基于vue-class-component的封装,可以直接点击这里查看vue-class-component的用法。

用法

下面介绍一些项目中常用的用法,具体文档可以查看这里

@Component

在项目中,使用@Component装饰器使您的类成为Vue组件:

<script>
import { Vue, Component } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
    ...
}
</script>

数据

data可以声明为类属性:

<template>
  <div>name: {{ name }}</div>
</template>

<script>
import { Vue, Component } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
    name = 'tom';
}
</script>

请注意,如果初始值为undefined,则类属性将不会响应,这意味着不会检测到属性的更改。为避免这种情况,您可以使用null或使用datahook

computed

computed可以声明为类属性的getter/setter:

<script>
import { Vue, Component } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
    book = 'tom';
    
    get bookname() {
        return `【${this.book}】`
    }
    
    set bookname(val) {
        this.book = val;
    }
}
</script>

Props

组件参数可以通过引入Prop装饰器来进行声明,格式如下:

@Prop(options: (PropOptions | Constructor[] | Constructor) = {})
<script>
import { Vue, Component, Prop } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
    @Prop(Number) readonly propA: number | undefined
    @Prop({ default: 'default value', type: String }) readonly propB: string | undefined
    @Prop([String, Boolean]) readonly propC: string | boolean | undefined
}
</script>

若不想每次都添加undefined,可以使用下面的写法:

@Prop(Number) readonly propA!: number

不过,需要注意的是,不要打开tsconfig.json中的compilerOptions.strict

Watch

数据监听可以使用Watch装饰圈,格式如下:

@Watch(path: string, options: WatchOptions = {})
<script>
import { Vue, Component, Watch } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
    @Watch('child')
    onChildChanged(val: string, oldVal: string) {}

    @Watch('person', { immediate: true, deep: true })
    onPersonChanged1(val: Person, oldVal: Person) {}

    @Watch('person')
    onPersonChanged2(val: Person, oldVal: Person) {}
}
</script>

等同于

export default {
  watch: {
    child: [
      {
        handler: 'onChildChanged',
        immediate: false,
        deep: false,
      },
    ],
    person: [
      {
        handler: 'onPersonChanged1',
        immediate: true,
        deep: true,
      },
      {
        handler: 'onPersonChanged2',
        immediate: false,
        deep: false,
      },
    ],
  },
  methods: {
    onChildChanged(val, oldVal) {},
    onPersonChanged1(val, oldVal) {},
    onPersonChanged2(val, oldVal) {},
  },
}

methods

methods的用法很简单,可直接声明为类原型方法:

<script>
import { Vue, Component } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
    hello() {
        console.log('Hello World!')
    }
}
</script>

组件

若页面中需要引入其他组件,需要在装饰器@Component进行配置。

<template>
  <OtherComponent />
</template>

<script>
import { Vue, Component } from 'vue-property-decorator';

import OtherComponent from './OtherComponent.vue'

@Component(
    components: {
        OtherComponent
    }
)
export default class HelloWorld extends Vue {
    ...
}
</script>

生命周期&钩子

生命周期函数及data、render方法,可以直接声明为类原型方法来进行使用:

<script>
import { Vue, Component } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
    mounted() {
        console.log('mounted')
    }
    
    data() {
        return {
            name: 'tom'
        }
    }
  
    render() {
       return <div>Hello World!</div>
    }
}
</script>

Model

组件中的model声明的格式如下:

@Model(event?: string, options: (PropOptions | Constructor[] | Constructor) = {})
<script>
import { Vue, Component, Model } from 'vue-property-decorator'

@Component
export default class YourComponent extends Vue {
  @Model('change', { type: Boolean }) readonly checked!: boolean
}
</script>

这样,在数据改变时,使用this.$emit('change', xxx)传参即可。

Mixins

mixins方法的话需要在声明class处进行修改:

<script>
import { Vue, Component, Mixins } from 'vue-property-decorator';

import MixinsComponent from './MixinsComponent.vue'

@Component
export default class HelloWorld extends Mixins(MixinsComponent) {
    ...
}
</script>

参考