欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Vue3.0 前的 TypeScript 最佳入門實(shí)踐

 更新時(shí)間:2019年06月18日 09:56:42   作者:前端勸退師  
這篇文章主要介紹了詳解Vue3.0 前的 TypeScript 最佳入門實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

我個(gè)人對(duì)更嚴(yán)格類型限制沒有積極的看法,畢竟各類轉(zhuǎn)類型的騷寫法寫習(xí)慣了。

然鵝最近的一個(gè)項(xiàng)目中,是 TypeScript + Vue ,毛計(jì)喇,學(xué)之...…真香!

注意此篇標(biāo)題的“前”,本文旨在講Ts混入框架的使用,不講Class API

1. 使用官方腳手架構(gòu)建

npm install -g @vue/cli
# OR
yarn global add @vue/cli

新的 Vue CLI 工具允許開發(fā)者 使用 TypeScript 集成環(huán)境 創(chuàng)建新項(xiàng)目。

只需運(yùn)行 vue create my-app 。

然后,命令行會(huì)要求選擇預(yù)設(shè)。使用箭頭鍵選擇 Manually select features 。

接下來,只需確保選擇了 TypeScriptBabel 選項(xiàng),如下圖:

完成此操作后,它會(huì)詢問你是否要使用 class-style component syntax 。

然后配置其余設(shè)置,使其看起來如下圖所示。

Vue CLI工具現(xiàn)在將安裝所有依賴項(xiàng)并設(shè)置項(xiàng)目。

接下來就跑項(xiàng)目喇。

總之,先跑起來再說。

2. 項(xiàng)目目錄解析

通過 tree 指令查看目錄結(jié)構(gòu)后可發(fā)現(xiàn)其結(jié)構(gòu)和正常構(gòu)建的大有不同。

這里主要關(guān)注 shims-tsx.d.tsshims-vue.d.ts 兩個(gè)文件

兩句話概括:

  • shims-tsx.d.ts ,允許你以 .tsx 結(jié)尾的文件,在 Vue 項(xiàng)目中編寫 jsx 代碼
  • shims-vue.d.ts 主要用于 TypeScript 識(shí)別 .vue 文件, Ts 默認(rèn)并不支持導(dǎo)入 vue 文件,這個(gè)文件告訴 ts 導(dǎo)入 .vue 文件都按 VueConstructor<Vue> 處理。

此時(shí)我們打開親切的 src/components/HelloWorld.vue ,將會(huì)發(fā)現(xiàn)寫法已大有不同

<template>
 <div class="hello">
 <h1>{{ msg }}</h1>
 <!-- 省略 -->
 </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
 @Prop() private msg!: string;
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

至此,準(zhǔn)備開啟新的篇章 TypeScript 極速入門 和 vue-property-decorator

3. TypeScript 極速入門

3.1 基本類型和擴(kuò)展類型

TypescriptJavascript 共享相同的基本類型,但有一些額外的類型。

  • 元組 Tuple
  • 枚舉 enum
  • AnyVoid

1. 基本類型合集

// 數(shù)字,二、八、十六進(jìn)制都支持
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;

// 字符串,單雙引都行
let name: string = "bob";
let sentence: string = `Hello, my name is ${ name }.

// 數(shù)組,第二種方式是使用數(shù)組泛型,Array<元素類型>:
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];

let u: undefined = undefined;
let n: null = null;

2. 特殊類型

1. 元組 Tuple

想象 元組 作為有組織的數(shù)組,你需要以正確的順序預(yù)定義數(shù)據(jù)類型。

const messyArray = [' something', 2, true, undefined, null];
const tuple: [number, string, string] = [24, "Indrek" , "Lasn"]

如果不遵循 為元組 預(yù)設(shè)排序的索引規(guī)則,那么 Typescript 會(huì)警告。

​ ( tuple 第一項(xiàng)應(yīng)為 number 類型)

2. 枚舉 enum *

enum 類型是對(duì)JavaScript標(biāo)準(zhǔn)數(shù)據(jù)類型的一個(gè)補(bǔ)充。 像C#等其它語言一樣,使用枚舉類型可以為一組數(shù)值賦予友好的名字。

// 默認(rèn)情況從0開始為元素編號(hào),也可手動(dòng)為1開始
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;

let colorName: string = Color[2];
console.log(colorName); // 輸出'Green'因?yàn)樯厦娲a里它的值是2

另一個(gè)很好的例子是使用枚舉來存儲(chǔ)應(yīng)用程序狀態(tài)。

3. Void

Typescript 中, 你必須在函數(shù)中定義返回類型 。像這樣:

若沒有返回值,則會(huì)報(bào)錯(cuò):

我們可以將其返回值定義為 void :

此時(shí)將無法 return

4. Any

Emmm...就是什么類型都行,當(dāng)你無法確認(rèn)在處理什么類型時(shí)可以用這個(gè)。

但要慎重使用,用多了就失去使用Ts的意義。

let person: any = "前端勸退師"
person = 25
person = true

主要應(yīng)用場(chǎng)景有:

  • 接入第三方庫
  • Ts菜逼前期都用

5. Never

用很粗淺的話來描述就是:" Never 是你永遠(yuǎn)得不到的爸爸。"

具體的行為是:

throw new Error(message)
return error("Something failed")
while (true) {} // 存在無法達(dá)到的終點(diǎn)

3. 類型斷言

簡(jiǎn)略的定義是:可以用來手動(dòng)指定一個(gè)值的類型。

有兩種寫法,尖括號(hào)和 as :

let someValue: any = "this is a string";

let strLength: number = (<string>someValue).length;
let strLength: number = (someValue as string).length;

使用例子有:

當(dāng) TypeScript 不確定一個(gè)聯(lián)合類型的變量到底是哪個(gè)類型的時(shí)候,我們只能訪問此聯(lián)合類型的所有類型里共有的屬性或方法:

function getLength(something: string | number): number {
 return something.length;
}

// index.ts(2,22): error TS2339: Property 'length' does not exist on type 'string | number'.
// Property 'length' does not exist on type 'number'.

如果你訪問長(zhǎng)度將會(huì)報(bào)錯(cuò),而有時(shí)候,我們確實(shí)需要在還不確定類型的時(shí)候就訪問其中一個(gè)類型的屬性或方法,此時(shí)需要斷言才不會(huì)報(bào)錯(cuò):

function getLength(something: string | number): number {
 if ((<string>something).length) {
 return (<string>something).length;
 } else {
 return something.toString().length;
 }
}

3.2 泛型: Generics

軟件工程的一個(gè)主要部分就是構(gòu)建組件,構(gòu)建的組件不僅需要具有明確的定義和統(tǒng)一的接口,同時(shí)也需要組件可復(fù)用。支持現(xiàn)有的數(shù)據(jù)類型和將來添加的數(shù)據(jù)類型的組件為大型軟件系統(tǒng)的開發(fā)過程提供很好的靈活性。

C#Java 中,可以使用"泛型"來創(chuàng)建可復(fù)用的組件,并且組件可支持多種數(shù)據(jù)類型。這樣便可以讓用戶根據(jù)自己的數(shù)據(jù)類型來使用組件。

1. 泛型方法

在TypeScript里, 聲明泛型方法 有以下兩種方式:

function gen_func1<T>(arg: T): T {
 return arg;
}
// 或者
let gen_func2: <T>(arg: T) => T = function (arg) {
 return arg;
}

調(diào)用方式也有兩種:

gen_func1<string>('Hello world');
gen_func2('Hello world'); 
// 第二種調(diào)用方式可省略類型參數(shù),因?yàn)榫幾g器會(huì)根據(jù)傳入?yún)?shù)來自動(dòng)識(shí)別對(duì)應(yīng)的類型。

2. 泛型與 Any

Ts 的特殊類型 Any 在具體使用時(shí),可以代替任意類型,咋一看兩者好像沒啥區(qū)別,其實(shí)不然:

// 方法一:帶有any參數(shù)的方法
function any_func(arg: any): any {
 console.log(arg.length);
		return arg;
}

// 方法二:Array泛型方法
function array_func<T>(arg: Array<T>): Array<T> {
	 console.log(arg.length);
		return arg;
}

方法一,打印了 arg 參數(shù)的 length 屬性。因?yàn)?any 可以代替任意類型,所以該方法在傳入?yún)?shù)不是數(shù)組或者帶有 length 屬性對(duì)象時(shí),會(huì)拋出異常。

方法二,定義了參數(shù)類型是 Array 的泛型類型,肯定會(huì)有 length 屬性,所以不會(huì)拋出異常。

3. 泛型類型

泛型接口:

interface Generics_interface<T> {
 (arg: T): T;
}
 
function func_demo<T>(arg: T): T {
 return arg;
}

let func1: Generics_interface<number> = func_demo;
func1(123); // 正確類型的實(shí)際參數(shù)
func1('123'); // 錯(cuò)誤類型的實(shí)際參數(shù)

3.3 自定義類型: Interface vs Type alias

Interface ,國(guó)內(nèi)翻譯成接口。

Type alias ,類型別名。

以下內(nèi)容來自:

Typescript 中的 interface 和 type 到底有什么區(qū)別

1. 相同點(diǎn) 都可以用來描述一個(gè)對(duì)象或函數(shù):

interface User {
 name: string
 age: number
}

type User = {
 name: string
 age: number
};

interface SetUser {
 (name: string, age: number): void;
}
type SetUser = (name: string, age: number): void;

都允許拓展(extends):

interfacetype 都可以拓展,并且兩者并不是相互獨(dú)立的,也就是說 interface 可以 extends type , type 也可以 extends interface 。 雖然效果差不多,但是兩者語法不同 。

interface extends interface

interface Name { 
 name: string; 
}
interface User extends Name { 
 age: number; 
}

type extends type

type Name = { 
 name: string; 
}
type User = Name & { age: number };

interface extends type

type Name = { 
 name: string; 
}
interface User extends Name { 
 age: number; 
}

type extends interface

interface Name { 
 name: string; 
}
type User = Name & { 
 age: number; 
}

2. 不同點(diǎn)

type 可以而 interface 不行

type 可以聲明基本類型別名,聯(lián)合類型,元組等類型

// 基本類型別名
type Name = string

// 聯(lián)合類型
interface Dog {
 wong();
}
interface Cat {
 miao();
}

type Pet = Dog | Cat

// 具體定義數(shù)組每個(gè)位置的類型
type PetList = [Dog, Pet]

type 語句中還可以使用 typeof 獲取實(shí)例的 類型進(jìn)行賦值

// 當(dāng)你想獲取一個(gè)變量的類型時(shí),使用 typeof
let div = document.createElement('div');
type B = typeof div

其他騷操作

type StringOrNumber = string | number; 
type Text = string | { text: string }; 
type NameLookup = Dictionary<string, Person>; 
type Callback<T> = (data: T) => void; 
type Pair<T> = [T, T]; 
type Coordinates = Pair<number>; 
type Tree<T> = T | { left: Tree<T>, right: Tree<T> };

interface 可以而 type 不行

interface 能夠聲明合并

interface User {
 name: string
 age: number
}

interface User {
 sex: string
}

/*
User 接口為 {
 name: string
 age: number
 sex: string 
}
*/

interface 有可選屬性和只讀屬性

可選屬性

接口里的屬性不全都是必需的。 有些是只在某些條件下存在,或者根本不存在。 例如給函數(shù)傳入的參數(shù)對(duì)象中只有部分屬性賦值了。帶有可選屬性的接口與普通的接口定義差不多,只是在可選屬性名字定義的后面加一個(gè) ? 符號(hào)。如下所示

interface Person {
 name: string;
 age?: number;
 gender?: number;
}

只讀屬性

顧名思義就是這個(gè)屬性是不可寫的,對(duì)象屬性只能在對(duì)象剛剛創(chuàng)建的時(shí)候修改其值。 你可以在屬性名前用 readonly 來指定只讀屬性,如下所示:

interface User {
 readonly loginName: string;
 password: string;
}

上面的例子說明,當(dāng)完成User對(duì)象的初始化后loginName就不可以修改了。

3.4 實(shí)現(xiàn)與繼承: implements vs extends

extends 很明顯就是ES6里面的類繼承,那么 implement 又是做什么的呢?它和 extends 有什么不同?

implement ,實(shí)現(xiàn)。與C#或Java里接口的基本作用一樣, TypeScript 也能夠用它來明確的強(qiáng)制一個(gè)類去符合某種契約

implement基本用法:

interface IDeveloper {
 name: string;
 age?: number;
}
// OK
class dev implements IDeveloper {
 name = 'Alex';
 age = 20;
}
// OK
class dev2 implements IDeveloper {
 name = 'Alex';
}
// Error
class dev3 implements IDeveloper {
 name = 'Alex';
 age = '9';
}

extends 是繼承父類,兩者其實(shí)可以混著用:

 class A extends B implements C,D,E

搭配 interfacetype 的用法有:

3.5 聲明文件與命名空間: declarenamespace

前面我們講到Vue項(xiàng)目中的 shims-tsx.d.tsshims-vue.d.ts ,其初始內(nèi)容是這樣的:

// shims-tsx.d.ts
import Vue, { VNode } from 'vue';

declare global {
 namespace JSX {
 // tslint:disable no-empty-interface
 interface Element extends VNode {}
 // tslint:disable no-empty-interface
 interface ElementClass extends Vue {}
 interface IntrinsicElements {
 [elem: string]: any;
 }
 }
}

// shims-vue.d.ts
declare module '*.vue' {
 import Vue from 'vue';
 export default Vue;
}

declare :當(dāng)使用第三方庫時(shí),我們需要引用它的聲明文件,才能獲得對(duì)應(yīng)的代碼補(bǔ)全、接口提示等功能。

這里列舉出幾個(gè)常用的:

  • declare var 聲明全局變量
  • declare function 聲明全局方法
  • declare class 聲明全局類
  • declare enum 聲明全局枚舉類型
  • declare global 擴(kuò)展全局變量
  • declare module 擴(kuò)展模塊

namespace :“內(nèi)部模塊”現(xiàn)在稱做“命名空間”

module X { 相當(dāng)于現(xiàn)在推薦的寫法 namespace X { )

跟其他 JS 庫協(xié)同

類似模塊,同樣也可以通過為其他 JS 庫使用了命名空間的庫創(chuàng)建 .d.ts 文件的聲明文件,如為 D3 JS 庫,可以創(chuàng)建這樣的聲明文件:

declare namespace D3{
 export interface Selectors { ... }
}
declare var d3: D3.Base;

所以上述兩個(gè)文件:

  • shims-tsx.d.ts , 在全局變量 global 中批量命名了數(shù)個(gè)內(nèi)部模塊。 shims-vue.d.ts ,意思是告訴 TypeScript *.vue 后綴的文件可以交給 vue 模塊來處理。

3.6 訪問修飾符: privatepublic 、 protected

其實(shí)很好理解:

  1. 默認(rèn)為 public
  2. 當(dāng)成員被標(biāo)記為 private 時(shí),它就不能在聲明它的類的外部訪問,比如:
class Animal {
 private name: string;
 constructor(theName: string) {
 this.name = theName;
 }
}

let a = new Animal('Cat').name; //錯(cuò)誤,‘name'是私有的

protectedprivate 類似,但是, protected 成員在派生類中可以訪問

class Animal {
 protected name: string;
 constructor(theName: string) {
 this.name = theName;
 }
}

class Rhino extends Animal {
 constructor() {
 super('Rhino');
 }  
 getName() {
 console.log(this.name) //此處的name就是Animal類中的name
 }
} 

3.7 可選參數(shù) ( ?: )和非空斷言操作符(!.)

可選參數(shù)

function buildName(firstName: string, lastName?: string) {
 return firstName + ' ' + lastName
}

// 錯(cuò)誤演示
buildName("firstName", "lastName", "lastName")
// 正確演示
buildName("firstName")
// 正確演示
buildName("firstName", "lastName")

非空斷言操作符:

能確定變量值一定不為空時(shí)使用。

與可選參數(shù) 不同的是,非空斷言操作符不會(huì)防止出現(xiàn) null 或 undefined。

let s = e!.name; // 斷言e是非空并訪問name屬性

4. Vue 組件的 Ts 寫法

從 vue2.5 之后,vue 對(duì) ts 有更好的支持。根據(jù)官方文檔,vue 結(jié)合 typescript ,有兩種書寫方式:

**Vue.extend **

 import Vue from 'vue'

 const Component = Vue.extend({
 	// type inference enabled
 })

vue-class-component

import { Component, Vue, Prop } from 'vue-property-decorator'

@Component
export default class Test extends Vue {
 @Prop({ type: Object })
 private test: { value: string }
}

理想情況下, Vue.extend 的書寫方式,是學(xué)習(xí)成本最低的。在現(xiàn)有寫法的基礎(chǔ)上,幾乎 0 成本的遷移。

但是 Vue.extend 模式,需要與 mixins 結(jié)合使用。在 mixin 中定義的方法,不會(huì)被 typescript 識(shí)別到

,這就意味著會(huì)出現(xiàn) 丟失代碼提示、類型檢查、編譯報(bào)錯(cuò)等問題。

菜鳥才做選擇,大佬都挑最好的。直接講第二種吧:

4.1 vue-class-component

我們回到 src/components/HelloWorld.vue

<template>
 <div class="hello">
 <h1>{{ msg }}</h1>
 <!-- 省略 -->
 </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
 @Prop() private msg!: string;
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

有寫過 python 的同學(xué)應(yīng)該會(huì)發(fā)現(xiàn)似曾相識(shí):

vue-property-decorator 這個(gè)官方支持的庫里,提供了函數(shù) **裝飾器(修飾符)**語法

1. 函數(shù)修飾符 @

“@”,與其說是修飾函數(shù)倒不如說是引用、調(diào)用它修飾的函數(shù)。

或者用句大白話描述: @ : "下面的被我包圍了。"

舉個(gè)栗子,下面的一段代碼,里面兩個(gè)函數(shù),沒有被調(diào)用,也會(huì)有輸出結(jié)果:

test(f){
 console.log("before ...");
 f()
		console.log("after ...");
 }

@test
func(){
	console.log("func was called");
}

直接運(yùn)行,輸出結(jié)果:

before ...
func was called
after ...

上面代碼可以看出來:

  1. 只定義了兩個(gè)函數(shù): testfunc ,沒有調(diào)用它們。
  2. 如果沒有“@test”,運(yùn)行應(yīng)該是沒有任何輸出的。

但是,解釋器讀到函數(shù)修飾符“@”的時(shí)候,后面步驟會(huì)是這樣:

  1. 去調(diào)用 test 函數(shù), test 函數(shù)的入口參數(shù)就是那個(gè)叫“ func ”的函數(shù);
  2. test 函數(shù)被執(zhí)行,入口參數(shù)的(也就是 func 函數(shù))會(huì)被調(diào)用(執(zhí)行);

換言之,修飾符帶的那個(gè)函數(shù)的入口參數(shù),就是下面的那個(gè)整個(gè)的函數(shù)。有點(diǎn)兒類似 JavaScrip t里面的 function a (function () { ... });

2. vue-property-decoratorvuex-class 提供的裝飾器

vue-property-decorator 的裝飾器:

vuex-class 的裝飾器:

  • @State
  • @Getter
  • @Action
  • @Mutation

我們拿原始Vue組件模版來看:

import {componentA,componentB} from '@/components';

export default {
	components: { componentA, componentB},
	props: {
 propA: { type: Number },
 propB: { default: 'default value' },
 propC: { type: [String, Boolean] },
 }
 // 組件數(shù)據(jù)
 data () {
 return {
 message: 'Hello'
 }
 },
 // 計(jì)算屬性
 computed: {
 reversedMessage () {
 return this.message.split('').reverse().join('')
 }
 // Vuex數(shù)據(jù)
 step() {
 	return this.$store.state.count
 }
 },
 methods: {
 changeMessage () {
 this.message = "Good bye"
 },
 getName() {
 	let name = this.$store.getters['person/name']
 	return name
 }
 },
 // 生命周期
 created () { },
 mounted () { },
 updated () { },
 destroyed () { }
}

以上模版替換成修飾符寫法則是:

import { Component, Vue, Prop } from 'vue-property-decorator';
import { State, Getter } from 'vuex-class';
import { count, name } from '@/person'
import { componentA, componentB } from '@/components';

@Component({
 components:{ componentA, componentB},
})
export default class HelloWorld extends Vue{
	@Prop(Number) readonly propA!: number | undefined
 @Prop({ default: 'default value' }) readonly propB!: string
 @Prop([String, Boolean]) readonly propC!: string | boolean | undefined
 
 // 原data
 message = 'Hello'
 
 // 計(jì)算屬性
	private get reversedMessage (): string[] {
 	return this.message.split('').reverse().join('')
 }
 // Vuex 數(shù)據(jù)
 @State((state: IRootState) => state . booking. currentStep) step!: number
	@Getter( 'person/name') name!: name
 
 // method
 public changeMessage (): void {
 this.message = 'Good bye'
 },
 public getName(): string {
 let storeName = name
 return storeName
 }
	// 生命周期
 private created ():void { },
 private mounted ():void { },
 private updated ():void { },
 private destroyed ():void { }
}

正如你所看到的,我們?cè)谏芷?列表那都添加 private XXXX 方法,因?yàn)檫@不應(yīng)該公開給其他組件。

而不對(duì) method 做私有約束的原因是,可能會(huì)用到 @Emit 來向父組件傳遞信息。

4.2 添加全局工具

引入全局模塊,需要改 main.ts :

import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';

Vue.config.productionTip = false;

new Vue({
 router,
 store,
 render: (h) => h(App),
}).$mount('#app');

npm i VueI18n

import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
// 新模塊
import i18n from './i18n';

Vue.config.productionTip = false;

new Vue({
 router, 
 store, 
 i18n, // 新模塊
 render: (h) => h(App),
}).$mount('#app');

但僅僅這樣,還不夠。你需要?jiǎng)?src/vue-shim.d.ts

// 聲明全局方法
declare module 'vue/types/vue' {
 interface Vue {
 readonly $i18n: VueI18Next;
 $t: TranslationFunction;
 }
}

之后使用 this.$i18n() 的話就不會(huì)報(bào)錯(cuò)了。

4.3 Axios 使用與封裝

Axios的封裝千人千面

如果只是想簡(jiǎn)單在Ts里體驗(yàn)使用Axios,可以安裝vue-axios

簡(jiǎn)單使用Axios

$ npm i axios vue-axios

main.ts添加:

import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'

Vue.use(VueAxios, axios)

然后在組件內(nèi)使用:

Vue.axios.get(api).then((response) => {
 console.log(response.data)
})

this.axios.get(api).then((response) => {
 console.log(response.data)
})

this.$http.get(api).then((response) => {
 console.log(response.data)
})

1. 新建文件 request.ts

文件目錄:

-api
 - main.ts // 實(shí)際調(diào)用
-utils
 - request.ts // 接口封裝

2. request.ts 文件解析

import * as axios from 'axios';
import store from '@/store';
// 這里可根據(jù)具體使用的UI組件庫進(jìn)行替換
import { Toast } from 'vant';
import { AxiosResponse, AxiosRequestConfig } from 'axios';
 
 /* baseURL 按實(shí)際項(xiàng)目來定義 */
const baseURL = process.env.VUE_APP_URL;

 /* 創(chuàng)建axios實(shí)例 */
const service = axios.default.create({
 baseURL,
 timeout: 0, // 請(qǐng)求超時(shí)時(shí)間
 maxContentLength: 4000,
});

service.interceptors.request.use((config: AxiosRequestConfig) => {
 return config;
}, (error: any) => {
 Promise.reject(error);
});

service.interceptors.response.use(
 (response: AxiosResponse) => {
 if (response.status !== 200) {
  Toast.fail('請(qǐng)求錯(cuò)誤!');
 } else {
  return response.data;
 }
 },
 (error: any) => {
 return Promise.reject(error);
 });
 
export default service;

為了方便,我們還需要定義一套固定的 axios 返回的格式,新建 ajax.ts

export interface AjaxResponse {
 code: number;
 data: any;
 message: string;
}

3. main.ts 接口調(diào)用:

// api/main.ts
import request from '../utils/request';

// get
export function getSomeThings(params:any) {
 return request({
 url: '/api/getSomethings',
 });
}

// post
export function postSomeThings(params:any) {
 return request({
 url: '/api/postSomethings',
 methods: 'post',
 data: params
 });
}

5. 編寫一個(gè)組件

為了減少時(shí)間,我們來替換掉 src/components/HelloWorld.vue ,做一個(gè)博客帖子組件:

<template>
	<div class="blogpost">
		<h2>{{ post.title }}</h2>
		<p>{{ post.body }}</p>
		<p class="meta">Written by {{ post.author }} on {{ date }}</p>
	</div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';

// 在這里對(duì)數(shù)據(jù)進(jìn)行類型約束
export interface Post {
	title: string;
	body: string;
	author: string;
	datePosted: Date;
}

@Component
export default class HelloWorld extends Vue {
	@Prop() private post!: Post;

	get date() {
		return `${this.post.datePosted.getDate()}/${this.post.datePosted.getMonth()}/${this.post.datePosted.getFullYear()}`;
	}
}
</script>

<style scoped>
h2 {
 text-decoration: underline;
}
p.meta {
 font-style: italic;
}
</style>

然后在 Home.vue 中使用:

<template>
 <div class="home">
 <img alt="Vue logo" src="../assets/logo.png">
 	<HelloWorld v-for="blogPost in blogPosts" :post="blogPost" :key="blogPost.title" />
 </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HelloWorld, { Post } from '@/components/HelloWorld.vue'; // @ is an alias to /src

@Component({
 components: {
 HelloWorld,
 },
})
export default class Home extends Vue {
 private blogPosts: Post[] = [
 {
  title: 'My first blogpost ever!',
  body: 'Lorem ipsum dolor sit amet.',
  author: 'Elke',
  datePosted: new Date(2019, 1, 18),
 },
 {
  title: 'Look I am blogging!',
  body: 'Hurray for me, this is my second post!',
  author: 'Elke',
  datePosted: new Date(2019, 1, 19),
 },
 {
  title: 'Another one?!',
  body: 'Another one!',
  author: 'Elke',
  datePosted: new Date(2019, 1, 20),
 },
 ];
}
</script>

這時(shí)候運(yùn)行項(xiàng)目:

這就是簡(jiǎn)單的父子組件

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論