Vue2.x使用Typescript

Posted 闹闹前端

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue2.x使用Typescript相关的知识,希望对你有一定的参考价值。

引言

本文翻译vue-class-component的使用方法。

原文地址

https://github.com/vuejs/vue-class-component#readme

使用vue-class-component

请使用ECMAScript stage 1 decorators.如果你使用了Babel则必须使用babel-plugin-transform-decorators-legacy. 如果你使用TypeScript,启用 --experimentalDecorators

它不支持第2阶段的装饰器,因为主流的转换器仍然会传送给旧的装饰器

注意:

  1. methods可以当作class的成员方法直接声明

  2. 计算属性可以当作class的属性声明

  3. 初始data可以当作class的属性声明(如果使用了babel必须引入babel-plugin-transform-class-properties)

  4. data, render和所有vue生命周期钩子都可以当作class的成员methods直接声明,但是你不能在初始化时调用它们。如果声明自定义方法,请避免使用保留字

  5. 对于其他的选项,通过装饰器函数传递它们

<template>
<div>
<input v-model="msg">
<p>prop:
{{propMessage}}</p>
<p>msg:
{{msg}}</p>
<p>helloMsg:
{{helloMsg}}</p>
<p>computed msg:
{{computedMsg}}</p>
<button @click="greet">Greet</button>
</div>
</template>

<script>
import Vue from 'vue'
import Component from 'vue-class-component'

@Component({
props: {
propMessage: String
}
})
export default class App extends Vue {
// initial data
msg = 123

// use prop values for initial data
helloMsg = 'Hello, ' + this.propMessage

// lifecycle hook
mounted () {
this.greet()
}

// computed
get computedMsg () {
return 'computed ' + this.msg
}

// method
greet () {
alert('greeting: ' + this.msg)
}
}
</script>

也可以试试由vue-property-decorators提供的@prop和@watch装饰器

使用Mixins

vue-class-component提供mixins助手函数以类的风格方式使用mixins.通过使用mixins助手,Typescript可以推断mixin的类型及继承它们到组件上

声明mixin例子

// mixin.js
import Vue from 'vue'
import Component from 'vue-class-component'

// You can declare a mixin as the same style as components.
@Component
export class MyMixin extends Vue {
mixinValue = 'Hello'
}

使用mixin例子

import Component, { mixins } from 'vue-class-component'
import MyMixin from './mixin.js'

// Use `mixins` helper function instead of `Vue`.
// `mixins` can receive any number of arguments.
@Component
export class MyComp extends mixins(MyMixin) {
created () {
console.log(this.mixinValue) // -> Hello
}
}

创建自定义装饰器

你可以通过创建你自己的装饰器来扩展这个库的功能.vue-class-component提供createDecorator助手创建自定义装饰器.createDecorator需要一个回调函数作为第一个参数,此回调函数将接收以下参数

  • options: Vue组件选项对象.此对象的更改将影响提供的组件

  • key: 装饰器应用的属性或方法关键字

  • parameterIndex:如果自定义装饰器被用作参数,此为装饰器参数的索引

NoCache装饰器示例

// decorators.js
import { createDecorator } from 'vue-class-component'

export const NoCache = createDecorator((options, key) => {
// component options should be passed to the callback
// and update for the options object affect the component
options.computed[key].cache = false
})
import { NoCache } from './decorators'

@Component
class MyComp extends Vue {
// the computed property will not be cached
@NoCache
get random () {
return Math.random()
}
}

添加自定义钩子

如果你使用Vue插件如Vue Router,你可以希望类组件调用它们提供的钩子.则Component.registerHooks允许你注册那样的钩子.

// class-component-hooks.js
import Component from 'vue-class-component'

// Register the router hooks with their names
Component.registerHooks([
'beforeRouteEnter',
'beforeRouteLeave',
'beforeRouteUpdate' // for vue-router 2.2+
])
// MyComp.js
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
class MyComp extends Vue {
// The class component now treats beforeRouteEnter
// and beforeRouteLeave as Vue Router hooks
beforeRouteEnter () {
console.log('beforeRouteEnter')
}

beforeRouteLeave () {
console.log('beforeRouteLeave')
}
}

注意:你必须在组件定义之前注册钩子

// main.js

// Make sure to register before importing any components
import './class-component-hooks'

import Vue from 'vue'
import MyComp from './MyComp'

new Vue({
el: '#app',
components: {
MyComp
}
})

Class属性的注意事项

vue-class-component通过实例化引擎底下的原始构造函数来收集类属性作为Vue实例数据.尽管我们可以像私有类那样定义实例数据,但我们有时需要知道它是如何工作的

  • 属性中的 this 

如果你定义了一个箭头函数作为类的属性并在里面使用this,那它并不会起作用.这是因为this只是在初始化类属性时,指向Vue实例的代理对象.

@Component
class MyComp extends Vue {
foo = 123

bar = () => {
// Does not update the expected property.
// `this` value is not a Vue instance in fact.
this.foo = 456
}
}

在那种情况下,你可以简单定义一个方法代替类属性,因为Vue会自动绑定这个实例.

@Component
class MyComp extends Vue {
foo = 123

bar () {
// Correctly update the expected property.
this.foo = 456
}
}
  • undefined不是响应式的

为了考虑Babel和TypeScript装饰器的一致性,vue-class-component不会使一个初始化为undefined的属性为响应式.你应该使用null作为初始值或使用data钩子去代替

@Component
class MyComp extends Vue {
// Will not be reactive
foo = undefined

// Will be reactive
bar = null

data () {
return {
// Will be reactive
baz: undefined
}
}
}


以上是关于Vue2.x使用Typescript的主要内容,如果未能解决你的问题,请参考以下文章

vue2.x老项目typescript改造过程经验总结

简单对比vue2.x与vue3.x响应式及新功能

如何在 Vue 2 和 TypeScript 中将 $refs 字段转换为其组件类型?

从Vue2.0到Vue3.0,哪些技术又要更新了?

typescript Angular 2测试片段。代码库https://developers.livechatinc.com/blog/category/programming/angular-2/

typescript Angular最终版本的Angular 2测试片段。代码库https://developers.livechatinc.com/blog/category/programming