如何在Vue項目中使用TypeScript


參考資料

typeScript 文檔

Vue 官方文檔 - TypeScript 支持

代碼地址

vue-ts

新建項目

vue create vue-ts
cd vue-ts
vue add @vue/typescript

項目配置,可以參考這篇文章 在 Vue+TypeScript 項目中,如何配置 ESLint 和 Prettier

類型注解和編譯時類型檢查

類型注解:變量后面通過冒號+類型來做類型注解

// test.ts
let title1: string; // 類型注解
title1 = "xbl"; // 正確
title1 = 4; // 錯誤
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"); }

函數

必填參:參數一旦聲明,就要求傳遞,且類型需符合

function greeting(person: string): string {
	return "Hello, " + person;
}
greeting('tom')

可選參數:參數名后面加上問號,變成可選參數

function greeting(person: string, msg?: string): string {
	return "Hello, " + person;
}

參數默認值

function greeting(person: string, msg = ''): string {
	return "Hello, " + person;
}

函數重載

// 聲明1
function info(a: {name: string}): string;
// 聲明2
function info(a: string): {name: string};
// 實現
function info(a: {name: string} | string): {name: string} | string {
  if (typeof a === "object") {
    return a.name;
  } else {
    return { name: a };
  }
}
console.log(info({ name: "tom" }));
console.log(info("tom"));

class的特性

ts中的類和es6中大體相同,這里重點關注ts帶來的特性

class MyComp {
  private _foo: string; // 私有屬性,不能在類的外部訪問
  protected bar: string;// 保護屬性,可以在子類中訪問
  // 構造函數參數加修飾符,能夠定義為成員屬性
  constructor(public tua = "tua") {}
  // 方法也有修飾符
  private someMethod() {}
  // 存取器:屬性方式訪問,可添加額外邏輯,控制讀寫性
  get foo() { return this._foo }
  set foo(val) { this._foo = val }
}

接口

接口僅約束結構,不要求實現,使用更簡單

interface Person {
  firstName: string;
  lastName: string;
}
function greeting(person: Person) {
	return 'Hello, ' + person.firstName + ' ' + person.lastName;
}
const user = {firstName: 'Jane', lastName: 'User'};
console.log(user);
console.log(greeting(user));

泛型

泛型(Generics)是指在定義函數、接口或類的時候,不預先指定具體的類型,而在使用的時候再指定
類型的一種特性。以此增加代碼通用性。

// 不用泛型
// interface Result {
// ok: 0 | 1;
// data: Feature[];
// }
// 使用泛型
interface Result<T> {
  ok: 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 { ok: 1, data }
}

裝飾器

裝飾器用於擴展類或者它的屬性和方法。@xxx就是裝飾器的寫法

組件聲明:@Component

典型應用是組件裝飾器@Component

@Component
export default class Hello extends Vue {}

屬性聲明:@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);
}

vuex使用:vuex-class

vuex-class 為vue-class-component提供Vuex狀態綁定幫助方法。

安裝依賴

npm i vuex-class -S

定義狀態,store.ts

import Vuex from "vuex";
import Vue from "vue";
Vue.use(Vuex);
export default new Vuex.Store({
  state: {
    features: [
      { id: 1, name: "類型", version: "1.0" },
      { id: 2, name: "編譯型語言", version: "1.0" },
    ],
  },
  mutations: {
    addFeatureMutation(state: any, featureName) {
    	state.features.push({ id: state.features.length + 1, name: featureName });
    },
  },
  actions: {
    addFeatureAction({ commit }, featureName) {
      commit("addFeatureMutation", featureName);
    },
  },
});

使用,Hello.vue

import { State, Action, Mutation } from "vuex-class";
@Component
export default class Feature extends Vue {
// 狀態、動作、變更映射
  @State features!: string[];
  @Action addFeatureAction: any;
  @Mutation addFeatureMutation: any;
  private addFeature(event) {
  console.log(event);
  // this.features.push(event.target.value);
  this.addFeatureAction(event.target.value);
  // this.addFeaturMutation(event.target.value);
  event.target.value = "";
  }
}

裝飾器原理

類裝飾器

//類裝飾器表達式會在運行時當作函數被調用,類的構造函數作為其唯一的參數。
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();

方法裝飾器

function dong(target: any, name: string, descriptor: any) {
	// 這里通過修改descriptor.value擴展了bar方法
  const baz = descriptor.value;
  descriptor.value = function(val: string) {
    console.log('dong~~');
    baz.call(this, val);
	}
	return descriptor
}
class Foo {
  @dong
  setBar(val: string) {
    this.bar = val
  }
}
foo.setBar('lalala')

屬性裝飾器

// 屬性裝飾器
function mua(target, name) {
	target[name] = 'mua~~~'
}
class Foo {
	@mua ns!:string;
}
console.log(foo.ns);

稍微改造一下使其可以接收參數

function mua(param:string) {
  return function (target, name) {
  	target[name] = param
  }
}

實戰一下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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM