Typescript
操作 | |
---|---|
新建一个基于ts的vue项目 | 自定义选项 - Manually select features;添加ts支持 - TypeScript;基于类的组件 - y; tslint |
在已存在项目中安装typescript | vue add @vue/typescript |
类型注解和编译时类型检查
变量后面通过冒号+类型来做类型注解
// test.ts
let title1: string; // 类型注解
title1 = "title1"; // 正确
title1 = 2; // 错误
let title2 = "xx"; // 类型推论
title2 = 2;// 错误
数组类型
let names: string[];
names = ['Tom'];//或Array<string>
任意类型
let foo:any;
foo = 'xx'
foo = 3
//any类型也可用于数组
let list: any[];
list = [1, true, "free"];
list[1] = 100;
函数中使用类型
function greeting(person: string): string {
return 'Hello, ' + person;
}
//void类型,常用于没有返回值的函数
function warnUser(): void { alert("This is my warning message"); }
例子,HelloWorld.vue
<template>
<div>
<input type="text" placeholder="输入新科目" @keyup.enter="addSubject">
<ul>
<li v-for="subject in subjects" :key="subject">{{subject}}</li>
</ul>
</div>
</template>
<script lang='ts'>
import { Component, Vue } from "vue-property-decorator";
@Component
export default class Hello extends Vue {
subjects: string[];
constructor() {
super();
this.subjects = ["语文", "数学"];
}
private addSubject(event: any) {
console.log(event);
this.subjects.push(event.target.value);
event.target.value = '';
}
}
</script>
类
ts中的类和es6中大体相同,重点关注ts带来的特性
class MyComp extends Parent {
// 访问修饰符
private _foo = 'foo'; // 私有属性,不能在类的外部访问
protected bar = 'bar';// 保护属性,还可以在派生类中访问
readonly mua = 'mua'; // 只读属性必须在声明时或构造函数里初始化
// 构造函数:初始化成员变量
// 参数加上修饰符,能够定义并初始化一个属性
constructor ( private tua = 'tua') {
super();
}
// 方法也有修饰符
private someMethod() {}
// 存取器:暴露存取数据时可添加额外逻辑;在vue里面可以用作计算属性
get foo() { return this._foo }
set foo(val) { this._foo = val }
}
const comp = new MyComp()
comp.foo
例子:利用getter设置计算属性
<template>
<li>特性数量:{{count}}</li>
</template>
<script lang="ts">
export default class HelloWorld extends Vue {
// 定义getter作为计算属性
get count() {
return this. subjects.length;
}
}
</script>
接口
接口仅约束结构,不要求实现,使用更简单
interface Person {
firstName: string;
lastName: string;
}
function greeting(person: Person) {
return 'Hello, ' + person.firstName + ' ' + person.lastName;
}
const user = {firstName: 'Jane', lastName: 'User'};
console.log(greeting(user));
例子:声明接口类型约束数据结构,HelloWorld.vue
<template>
<div>
<input type="text" placeholder="输入新科目" @keyup.enter="addSubject" />
<ul>
<li v-for="subject in subjects" :key="subject.id">{{subject.name}}</li>
</ul>
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
interface Subject {
id: number;
name: string;
}
@Component
export default class HelloWorld extends Vue {
private subjects: Subject[];
constructor() {
super();
this.subjects = [
{ id: 1, name: "语文" },
{ id: 2, name: "数学" }
];
}
private addSubject(event: any) {
console.log(event);
this.subjects.push({ id:this.subjects.length + 1, name: event.target.value });
event.target.value = "";
}
}
</script>
泛型
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定
类型的一种特性。
// 不用泛型
// interface Result {
// data: Feature[];
// }
// 使用泛型
interface Result<T> {
data: T;
}
例子:使用泛型约束接口返回类型
function getData<T>(): Result<T> {
const data: any = [
{ id: 1, name: "类型注解", version: "2.0" },
{ id: 2, name: "编译型语言", version: "1.0" }
];
return { data };
}
使用接口
constructor() {
this.features = getData<Feature[]>().data;
}
甚至返回Promise
function getData<T>(): Promise<Result<T>> {
const data: any = [
{ id: 1, name: "类型注解", version: "2.0" },
{ id: 2, name: "编译型语言", version: "1.0" }
];
return Promise.resolve<Result<T>>({ data });
}
使用
async mounted() {
this.features = (await getData<Feature[]>()).data;
}
装饰器
装饰器用于扩展类或者它的属性和方法。
属性声明:@Prop
除了在@Component中声明,还可以采用@Prop的方式声明组件属性
export default class HelloWorld extends Vue {
// Props()参数是为vue提供属性选项
// !称为明确赋值断言,它是提供给ts的
@Prop({type: String, required: true})
private msg!: string;
}
事件处理:@Emit
新增特性时派发事件通知,Hello.vue
// 通知父类新增事件,若未指定事件名则函数名作为事件名(羊肉串形式)
@Emit()
private addFeature(event: any) {// 若没有返回值形参将作为事件参数
const feature = { name: event.target.value, id: this.features.length + 1 };
this.features.push(feature);
event.target.value = "";
return feature;// 若有返回值则返回值作为事件参数
}
变更监测:@Watch
@Watch('msg')
onRouteChange(val:string, oldVal:any){
console.log(val, oldVal);
}
装饰器原理
装饰器本质是工厂函数,修改传入的类、方法、属性等
类装饰器
//类装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数。
function log(target: Function) {
// target是构造函数
console.log(target === Foo); // true
target.prototype.log = function() {
console.log(this.bar);
}
// 如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明。
}
@log
class Foo {
bar = 'bar'
}
const foo = new Foo();
// @ts-ignore
foo.log();
Component例子,新建Decor.vue
<template>
<div>{{msg}}</div>
</template>
<script lang='ts'>
import { Vue } from "vue-property-decorator";
function Component(options: any) {
return function(target: any) {
return Vue.extend(options);
};
}
@Component({
props: {
msg: {
type: String,
default: ""
}
}
})
export default class Decor extends Vue {}
</script>
网友评论