国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

Vue新搭檔TypeScript快速入門(mén)實(shí)踐記錄

發(fā)布時(shí)間:2021-08-17 12:16 來(lái)源: 閱讀:0 作者:JackieDYH 欄目: JavaScript 歡迎投稿:712375056

目錄

Vue官方從2.6.X版本開(kāi)始就部分使用Ts重寫(xiě)了。

我個(gè)人對更嚴格類(lèi)型限制沒(méi)有積極的看法,畢竟各類(lèi)轉類(lèi)型的騷寫(xiě)法寫(xiě)習慣了。

最近的一個(gè)項目中,是TypeScriptVue,毛計喇,學(xué)之...…真香!

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

1. 使用官方腳手架構建

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

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

只需運行vue create my-app。

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

接下來(lái),只需確保選擇了TypeScriptBabel選項,如下圖:

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

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

Vue CLI工具現在將安裝所有依賴(lài)項并設置項目。

接下來(lái)就跑項目

2. 項目目錄解析

通過(guò)tree指令查看目錄結構后可發(fā)現其結構和正常構建的大有不同。

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

兩句話(huà)概括:

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

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

<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>

至此,準備開(kāi)啟新的篇章 TypeScript極速入門(mén) 和 vue-property-decorator

3. TypeScript極速入門(mén)

 3.1 基本類(lèi)型和擴展類(lèi)型

TypescriptJavascript共享相同的基本類(lèi)型,但有一些額外的類(lèi)型。

  • 元組 Tuple
  • 枚舉 enum
  • Any 與Void

1. 基本類(lèi)型合集

// 數字,二、八、十六進(jìn)制都支持
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
 
// 字符串,單雙引都行
let name: string = "bob";
let sentence: string = `Hello, my name is ${ name }.
 
// 數組,第二種方式是使用數組泛型,Array<元素類(lèi)型>:
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];
 
let u: undefined = undefined;
let n: null = null;

2. 特殊類(lèi)型

1. 元組 Tuple

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

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

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

​ (tuple第一項應為number類(lèi)型)

2. 枚舉 enum

enum類(lèi)型是對JavaScript標準數據類(lèi)型的一個(gè)補充。 像C#等其它語(yǔ)言一樣,使用枚舉類(lèi)型可以為一組數值賦予友好的名字。

// 默認情況從0開(kāi)始為元素編號,也可手動(dòng)為1開(kāi)始
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;
 
let colorName: string = Color[2];
console.log(colorName);  // 輸出'Green'因為上面代碼里它的值是2

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

3. Void

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

若沒(méi)有返回值,則會(huì )報錯:

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

此時(shí)將無(wú)法 return

4. Any

emmm...就是什么類(lèi)型都行,當你無(wú)法確認在處理什么類(lèi)型時(shí)可以用這個(gè)。

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

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

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

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

5. Never

用很粗淺的話(huà)來(lái)描述就是:"Never是你永遠得不到的爸爸。"

具體的行為是:

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

3. 類(lèi)型斷言

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

有兩種寫(xiě)法,尖括號和as:

let someValue: any = "this is a string";
 
let strLength: number = (<string>someValue).length;
let strLength: number = (someValue as string).length;

使用例子有:

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

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'.

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

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

3.2 泛型:Generics

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

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

1. 泛型方法

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

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

調用方式也有兩種:

gen_func1<string>('Hello world');
gen_func2('Hello world'); 
// 第二種調用方式可省略類(lèi)型參數,因為編譯器會(huì )根據傳入參數來(lái)自動(dòng)識別對應的類(lèi)型。

2. 泛型與Any

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

    // 方法一:帶有any參數的方法
    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參數的length屬性。因為any可以代替任意類(lèi)型,所以該方法在傳入參數不是數組或者帶有length屬性對象時(shí),會(huì )拋出異常。
  • 方法二,定義了參數類(lèi)型是Array的泛型類(lèi)型,肯定會(huì )有length屬性,所以不會(huì )拋出異常。

3. 泛型類(lèi)型

泛型接口:

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);     // 正確類(lèi)型的實(shí)際參數
func1('123');   // 錯誤類(lèi)型的實(shí)際參數

3.3 自定義類(lèi)型:Interface vs Type alias

Interface,國內翻譯成接口。

Type alias,類(lèi)型別名。

1. 相同點(diǎn)

都可以用來(lái)描述一個(gè)對象或函數:

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):

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

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 可以聲明基本類(lèi)型別名,聯(lián)合類(lèi)型,元組等類(lèi)型

// 基本類(lèi)型別名
type Name = string
 
// 聯(lián)合類(lèi)型
interface Dog {
    wong();
}
interface Cat {
    miao();
}
 
type Pet = Dog | Cat
 
// 具體定義數組每個(gè)位置的類(lèi)型
type PetList = [Dog, Pet]

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

// 當你想獲取一個(gè)變量的類(lèi)型時(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 有可選屬性和只讀屬性

可選屬性

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

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

只讀屬性

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

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

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

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

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

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

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是繼承父類(lèi),兩者其實(shí)可以混著(zhù)用:

 class A extends B implements C,D,E

搭配 interfacetype的用法有:

3.5 聲明文件與命名空間:declare 和 namespace

前面我們講到Vue項目中的shims-tsx.d.tsshims-vue.d.ts,其初始內容是這樣的:

// 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:當使用第三方庫時(shí),我們需要引用它的聲明文件,才能獲得對應的代碼補全、接口提示等功能。

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

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

namespace:“內部模塊”現在稱(chēng)做“命名空間”

module X { 相當于現在推薦的寫(xiě)法 namespace X {)

跟其他 JS 庫協(xié)同

類(lèi)似模塊,同樣也可以通過(guò)為其他 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中批量命名了數個(gè)內部模塊。
  • shims-vue.d.ts,意思是告訴 TypeScript *.vue 后綴的文件可以交給 vue 模塊來(lái)處理。

3.6 訪(fǎng)問(wèn)修飾符:private、public、protected

其實(shí)很好理解:

  1. 默認為public
  2. 當成員被標記為private時(shí),它就不能在聲明它的類(lèi)的外部訪(fǎng)問(wèn),比如:
class Animal {
    private name: string;
    constructor(theName: string) {
        this.name = theName;
    }
}
 
let a = new Animal('Cat').name; //錯誤,‘name'是私有的

protectedprivate類(lèi)似,但是,protected成員在派生類(lèi)中可以訪(fǎng)問(wèn)

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類(lèi)中的name
   }
}

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

可選參數

function buildName(firstName: string, lastName?: string) {
    return firstName + ' ' + lastName
}
 
// 錯誤演示
buildName("firstName", "lastName", "lastName")
// 正確演示
buildName("firstName")
// 正確演示
buildName("firstName", "lastName")

非空斷言操作符:

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

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

let s = e!.name;  // 斷言e是非空并訪(fǎng)問(wèn)name屬性

拓展 

1. 屬性或參數中使用 ?:表示該屬性或參數為可選項

2. 屬性或參數中使用 ?。罕硎緩娭平馕觯ǜ嬖Vtypescript編譯器,這里一定有值),常用于vue-decorator中的@Prop

3. 變量后使用 ?。罕硎绢?lèi)型推斷排除null、undefined

4. Vue組件的Ts寫(xiě)法

從 vue2.5 之后,vue 對 ts 有更好的支持。根據官方文檔,vue 結合 typescript ,有兩種書(shū)寫(xiě)方式:

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 的書(shū)寫(xiě)方式,是學(xué)習成本最低的。在現有寫(xiě)法的基礎上,幾乎 0 成本的遷移。

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

,這就意味著(zhù)會(huì )出現丟失代碼提示、類(lèi)型檢查、編譯報錯等問(wèn)題。

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

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>

有寫(xiě)過(guò)python的同學(xué)應該會(huì )發(fā)現似曾相識:

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

1. 函數修飾符 @

“@”,與其說(shuō)是修飾函數倒不如說(shuō)是引用、調用它修飾的函數。

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

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

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

直接運行,輸出結果:

before ...
func was called
after ...

上面代碼可以看出來(lái):

  • 只定義了兩個(gè)函數:testfunc,沒(méi)有調用它們。
  • 如果沒(méi)有 @test,運行應該是沒(méi)有任何輸出的。

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

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

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

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

vue-property-decorator的裝飾器:

  • @Prop
  • @PropSync
  • @Provide
  • @Model
  • @Watch
  • @Inject
  • @Provide
  • @Emit
  • @Component (provided by vue-class-component)
  • Mixins (the helper function named mixins provided by vue-class-component)

vuex-class的裝飾器:

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

我們拿原始Vue組件模版來(lái)看:

import {componentA,componentB} from '@/components';
 
export default {
	components: { componentA, componentB},
	props: {
    propA: { type: Number },
    propB: { default: 'default value' },
    propC: { type: [String, Boolean] },
  }
  // 組件數據
  data () {
    return {
      message: 'Hello'
    }
  },
  // 計算屬性
  computed: {
    reversedMessage () {
      return this.message.split('').reverse().join('')
    }
    // Vuex數據
    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 () { }
}

以上模版替換成修飾符寫(xiě)法則是:

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'
  
  // 計算屬性
	private get reversedMessage (): string[] {
  	return this.message.split('').reverse().join('')
  }
  // Vuex 數據
  @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 { }
}

正如你所看到的,我們在生命周期 列表那都添加private XXXX方法,因為這不應該公開(kāi)給其他組件。

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

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');

但僅僅這樣,還不夠。你需要動(dòng)src/vue-shim.d.ts

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

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

4.3 Axios 使用與封裝

Axios的封裝千人千面

如果只是想簡(jiǎn)單在Ts里體驗使用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)

然后在組件內使用:

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í)際調用
-utils
    - request.ts  // 接口封裝

2. request.ts文件解析

import * as axios from 'axios';
import store from '@/store';
// 這里可根據具體使用的UI組件庫進(jìn)行替換
import { Toast } from 'vant';
import { AxiosResponse, AxiosRequestConfig } from 'axios';
 
 /* baseURL 按實(shí)際項目來(lái)定義 */
const baseURL = process.env.VUE_APP_URL;
 
 /* 創(chuàng  )建axios實(shí)例 */
const service = axios.default.create({
    baseURL,
    timeout: 0, // 請求超時(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('請求錯誤!');
        } 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接口調用:

// 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. 編寫(xiě)一個(gè)組件

為了減少時(shí)間,我們來(lái)替換掉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';
 
// 在這里對數據進(jìn)行類(lèi)型約束
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í)候運行項目:

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

而關(guān)于Class API撤銷(xiāo),其實(shí)還是挺舒服的。 用class 來(lái)編寫(xiě) Vue組件確實(shí)太奇怪了。 (所以本篇Ts入門(mén)壓根沒(méi)寫(xiě)Class API)

以上就是Vue新搭檔TypeScript快速入門(mén)實(shí)踐的詳細內容,更多關(guān)于Vue TypeScript快速入門(mén)的資料請關(guān)注腳本之家其它相關(guān)文章!

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

vue
成人国产一区二区三区| 国语自产拍精品香蕉在线播放| 亚洲乱亚洲乱少妇无码99P| 日本VA在线视频播放| 国产免费永久精品无码| 色天天躁夜夜躁天干天干|