-
类型注解:在声明变量时就要定义好变量类型
- 常见内置类型:string、number、boolean、void、any
// 类型注解:指定变量为字符串
let title: string;
// 直接赋值触发类型推论
let name = 'asher';
// 正确的变量类型可以直接赋值
title = '1';
// 不被允许
title = 1
// 不被允许
name = 6
// 数组类型,定义为字符串数组
let names: string[];
// 可直接赋值填充数据
names = ['asher', 'tom'];
// 不被允许
names = ['asher', 'tom',4]
// 多类型约束,数组中的元素可以是字符串或数字类型
let datas: (string | number)[];
datas = ['info', 3, 2];
// 任意类型,数组中元素可以为任意类型
let list: any[];
list = ['free', false, 2, {}];
// 函数中使用类型注解
// person: string 约束形参类型为string
// function greeting (): string 表示约定返回值类型为string
function greeting (person: string): string {
return `hello, ${person}`;
}
greeting('tom');
// 不被允许
greeting(123)
// void类型 表示函数没有返回值
function warn(): void {
alert('warning!!!');
}
// ts函数中参数如果声明了,就是必选参数
function sayHello1 (name: string, age: number): string {
return `name age`
}
sayHello1('tom', 20)
// 不被允许,已声明参数必填
sayHello1('tom')
// ts函数传递可选参的方式
// 1. 用?声明age为可选参
function sayHello2 (name: string, age?: number): string {
return `name age`
}
// age可选
sayHello2('tom')
// 2. 声明age参数时有默认值,即age不传参时值为20,同时返回值类型约定为string | number
function sayHello3 (name: string, age: number = 20): string | number {
return `name age`
}
sayHello3('tom')
// 函数重载,多个同名函数,通过 参数数量 或者 类型不同 或者 返回值不同 区分
// ts的重载,先声明,再实现
function info(a: {name: string}): string
function info(a: string): object
function info(a: any): any{
if(typeof a === 'object') {
return a.name;
}else {
return {name: a}
}
}
info({name: 'jerry'})
-
在vue文件中用ts语法书写、渲染组件
- 在类中声明变量时,private 仅当前类可以使用,protected 子类可用、派生类可用,public 公共性质
@Component
export default class Hello extends Vue {
// 装饰器
/*
可理解为原组件中的props属性:
props: {
msg: {
type: String,
required: true
}
}
*/
// !表示属性msg为必填项,约定为string类型
@Prop() private msg!: string;
// ?表示属性为可选属性,default表示变量默认值,不赋值的情况下值为默认值
@Prop({default: 'asher'}) private name?: string;
// obj约定为对象类型,并且必须包含foo属性,foo的值为string类型
@Prop() private obj: {foo: string};
// 声明的普通属性,相当于组件的data
private features = ['静态类型','编译']
// 生命周期函数直接调用即可
created () {
// ...
}
// 计算属性get,可理解为computed
get featureCount () {
return this.features.length
}
// watch语法
@Watch('msg')
onRouteChange(val: string, oldVal: any) {
console.log(val, oldVal)
}
// 事件方法直接写就可以,这里就相当于原先的methods
addFeature(event: any){
this.features.push(event.target.value)
event.target.value = ''
}
}
<template>
<div>
{{msg}}-{{name}}
<p>
<input
type="text"
placeholder="请输入特性名称"
@keyup.enter="addFeature"
>
</p>
<ul>
<li
v-for="f in features"
:key="f"
>{{f}}</li>
<li>特性数量:{{featureCount}}</li>
</ul>
</div>
</template>
class Shape {
// readonly的变量要求必须初始化,可以在定义的时候赋值,也可以在构造器传参的时候赋值
readonly foo: string = 'foo'
// 参数属性:给构造函数的参数加上修饰符,能够定义并初始化一个成员属性,也就是说不需要另外定义声明
// 写法1:(繁琐),先声明变量,再定义,再赋值
area: number
protected color: string
constructor(color: string, width: number, height: number){
this.area = width * height
this.color = color
}
// 写法2:(省略color单独的定义、声明)
area: number
constructor(public color: string, width: number, height: number){
this.area = width * height
}
// 类的方法:
shoutout () {
return `i am ${this.color} with area of ${this.area} cm squared`
}
}
// 从Shape类继承来的
class Square extends Shape {
constructor(color: string, side: number) {
super(color, side, side)
console.log(this.color)
}
shoutout () {
return `我是${this.color}面积是${this.area}平方厘米`
}
}
class Feature {
constructor(public id: number, public name: string, public version: string){}
}
// 在组件中,声明普通属性的时候,如果数据结构符合类的数据结构,则默认允许声明
private features: Feature[] = [
{id: 1, name: '静态类型', version: '1.0'},
{id: 2, name: '编译', version: '1.0'}
]
-
存取器、私有变量
- 类的属性都是私有变量,可以通过set、get存取暴露出去
class Employee {
private firstName: string = "Mike James"
private lastName: string = "Mike James"
getFullName (): string {
return `${this.firstName} ${this.lastName}`
}
setFullName (newName: string) {
console.log('您修改了用户名!')
this.firstName = newName.split(' ')[0]
this.lastName = newName.split(' ')[1]
}
}
const exployee = new Employee()
// 接口约束结构
// 当使用class的时候,要初始化等等,单纯的只需要约束数据类型的话使用接口约束比较方便
interface Person {
firstName: string;
lastName: string;
sayHello(): string
}
// 传参的时候要求必须传和Person一样的结构
function greeting1 (person: Person) {
return `Hello ${person.firstName} ${person.lastName}`
}
// 只要满足包含Person内部的结构就ok
const user1 = {firstName:'Jane',lastName: 'User',foo:123}
const user3 = {firstName:'Jane',lastName: 'User',sayHello: () => {return 'lsls'}}
greeting1(user3)
// 不被允许,缺少lastName属性
const user2 = {lastName: 'User',foo:123}
// 没有按数据结构传sayHello方法,报错
greeting1(user)
// 类实现上面Person接口
class Greeter implements Person {
constructor(public firstName='', public lastName=''){}
sayHello () {
return `Hello ${this.firstName} ${this.lastName}`
}
}
const user4 = new Greeter('Jane', 'Asher')
// 调用方法时,只要结构满足接口就可以使用
greeting1(user4)
// 从接口获取来的数据,我们可以做个结构约束
interface Result<T> {
code: 0 | 1,
data: T[]
}
// 泛型函数
function getData<T>(): Result<T> {
const data: any[] = [
{id: '1', name: '类型注解', version: '2.0'},
{id: '2', name: '编译型语言', version: '1.0'}
];
return {code: 1, data}
}
// 在组件中使用泛型函数
// 泛型函数 先定义一个泛型函数,在调用泛型函数时必须指定函数返回的类型
function getData<T>(): Promise<Result<T>> {
const data: any[] = [
{id: '1', name: '类型注解', version: '2.0'},
{id: '2', name: '编译型语言', version: '1.0'}
];
return Promise.resolve({code: 1, data} as Result<T>)
}
export default class Hello extends Vue {
async created () {
const result = await getData<Feature>()
this.features = result.data
}
}
// 添加数组新元素的时候,同时派发事件
// 1. 如果@Emit()不传参,则默认事件名称为方法名add-Feature
// 2. 事件传参,如果函数有返回值,则默认传参返回值,如果没有,则默认为函数形参
// 在Hello.vue中声明事件
export class Feature {
constructor(public id: number, public name: string, public version: string){}
}
@Emit()
private addFeature(event: any) {
const feature = {
name: event.target.value,
id: this.features.length + 1,
version: '1.0'
}
this.features.push(feature)
event.target.value = ''
return feature;
}
// 在APP.vue中接收事件
<template>
<div id="app">
<Hello
msg="i am msg"
@add-feature="onAddFeature"
></Hello>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import Hello, {Feature}from './components/Hello.vue';
@Component({
components: {
Hello,
},
})
export default class App extends Vue {
onAddFeature (feature: Feature) {
console.log(feature.name)
}
}
</script>
网友评论