Vue の新しいパートナー TypeScript クイックスタート実践記録

Vue の新しいパートナー TypeScript クイックスタート実践記録

Vueバージョン2.6.X以降、 Tsを使用して一部のコンポーネントを正式に書き直しました。

個人的には、ジャンルの制限を厳しくすることには賛成できません。結局のところ、私たちはジャンルを変えるようなさまざまな執筆スタイルに慣れているのです。

私の最近のプロジェクトの 1 つはTypeScript + Vueです。素晴らしいアイデアですね。学んでみます...本当に楽しいです!

この記事のタイトルの「前」に注意してください。この記事の目的は、 Class APIではなく、 Tsミックスイン フレームワークの使用について説明することです。

1. 公式の足場を使って構築する

npm インストール -g @vue/cli
# または
糸グローバル追加 @vue/cli

新しいVue CLIツールを使用すると、開発者はTypeScript統合した新しいプロジェクトを作成できます。

vue create my-app実行するだけです。

次に、コマンド ラインでプリセットを選択するように求められます。矢印キーを使用してManually select features

次に、以下に示すように、 TypeScriptBabelオプションが選択されていることを確認します。

画像-20190611163034679

これを実行したら、 class-style component syntaxを使用するかどうかを尋ねられます。

次に、残りの設定を下の画像のように構成します。

画像-20190611163127181

Vue CLI ツールはすべての依存関係をインストールし、プロジェクトをセットアップします。

画像-20190611163225739

次にプロジェクトを実行します

2. プロジェクトディレクトリ分析

treeコマンドを使用してディレクトリ構造を表示すると、その構造が通常のビルドとは大きく異なることがわかります。

画像-20190611163812421

ここではshims-tsx.d.tsshims-vue.d.ts 2つのファイルに焦点を当てます。

要約すると次の 2 つの文になります。

  • shims-tsx.d.ts使用すると、 .tsxで終わるファイルを持つVueプロジェクトでjsxコードを記述できます。
  • shims-vue.d.tsは主にTypeScript.vueファイルを識別するために使用されます。Ts Tsデフォルトではvueファイルのインポートをサポートしていません。このファイルはts.vueファイルをインポートし、 VueConstructor<Vue>に従って処理するように指示します。

さて、おなじみのsrc/components/HelloWorld.vueを開くと、記述方法が大きく異なることがわかります。

<テンプレート>
  <div class="hello">
    <h1>{{ メッセージ }}</h1>
    <!-- 省略 -->
  </div>
</テンプレート>
 
<script lang="ts">
'vue-property-decorator' から { Component, Prop, Vue } をインポートします。
 
@成分
デフォルトのクラスHelloWorldをエクスポートし、Vueを拡張します。
  @Prop() プライベートメッセージ!: 文字列;
}
</スクリプト>
 
<!-- CSS をこのコンポーネントのみに制限するために "scoped" 属性を追加します -->
<スタイル スコープ></style>

この時点で、新しい章を始める準備が整いましたTypeScriptクイックスタートとvue-property-decorator

3. TypeScript のクイックスタート

3.1 基本型と拡張型

Typescript Javascriptと同じ基本型を共有しますが、いくつかの追加の型があります。

  • Tuple
  • enum
  • AnyかつVoid

1. 基本型コレクション

// 数値、2進数、8進数、16進数はすべてサポートされています let decLiteral: number = 6;
hexLiteral: 数値 = 0xf00d;
 
// 文字列、一重引用符または二重引用符は OK です let name: string = "bob";
let sentence: string = `こんにちは、私の名前は${ name }です。
 
// 配列、2 番目の方法は配列ジェネリックを使用することです。Array<要素の型>:
リスト: number[] = [1, 2, 3];
リスト: 配列<数値> = [1, 2, 3];
 
u: undefined = undefined とします。
n: null = null とします。

2. 特殊なタイプ

1. Tuple

タプルは、データ型を正しい順序で事前に定義する必要がある整理された配列と考えてください。

const messyArray = ['something', 2, true, undefined, null];
定数タプル: [数値、文字列、文字列] = [24、"Indrek"、"Lasn"]

Typescript 、タプルの事前設定された順序のインデックス作成ルールに従わない場合に警告を表示します。

画像-20190611174515658

( tuple最初の項目はnumber型である必要があります)

2. enum

enum型は、JavaScript 標準データ型の補足です。 C# や他の言語と同様に、列挙型を使用して値のセットにわかりやすい名前を付けることができます。

// デフォルトでは要素番号は 0 から始まりますが、手動で 1 から始めることもできます enum Color {Red = 1、Green = 2、Blue = 4}
c:Color = Color.Green; とします。
 
colorName: 文字列 = Color[2];
console.log(colorName); // 上記のコードでは値が 2 なので、「Green」を出力します。

もう 1 つの優れた例は、列挙型を使用してアプリケーションの状態を保存することです。

画像-20190611175542886

3. Void

Typescriptでは、関数内に戻り値の型を定義する必要があります。このような:

画像-20190611175858587

戻り値がない場合、エラーが報告されます。

画像-20190611175932713

戻り値をvoidとして定義できます。

画像-20190611180043827

現時点ではreturnはできません

4. Any

えーっと…どんなタイプでも大丈夫です。どんなタイプを扱っているのかわからないときに使えます。

しかし、使いすぎると T を使用する目的が達成されなくなるため、注意して使用する必要があります。

let person: any = "フロントエンド説得教師"
人 = 25
人 = 真実

主な適用シナリオは次のとおりです。

  • サードパーティのライブラリへのアクセス
  • TS初心者は初期段階でそれを使用します

5. Never

簡単に言えば、「 Never得られない父親」です。

具体的な動作は次のとおりです。

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

画像-20190611181410052

3. 型アサーション

簡単に定義すると、値の型を手動で指定するために使用できます。

これを記述する方法には、山括弧とas 2 つの方法があります。

let someValue: any = "これは文字列です";
 
strLength: number = (<文字列>someValue).length; とします。
strLength: number = (someValue as string).length; とします。

使用例としては次のようなものがあります。

TypeScript がユニオン型の変数の型を不明な場合は、ユニオン型のすべての型に共通するプロパティまたはメソッドにのみアクセスできます。

関数 getLength(何か: 文字列 | 数値): 数値 {
    something.length を返します。
}
 
// index.ts(2,22): エラー TS2339: プロパティ 'length' は型 'string | number' に存在しません。
// プロパティ 'length' はタイプ 'number' には存在しません。

長さにアクセスすると、エラーが報告されます。型がまだ決定されていないときに、型のプロパティまたはメソッドにアクセスする必要がある場合があります。このとき、エラーを回避するにはアサーションが必要です。

関数 getLength(何か: 文字列 | 数値): 数値 {
    if ((<文字列>something).length) {
        (<文字列>something).length を返します。
    } それ以外 {
        something.toString().length を返します。
    }
}

3.2 ジェネリック

ソフトウェア エンジニアリングの主要部分はコンポーネントの構築です。構築されたコンポーネントは明確な定義と統一されたインターフェースを持つ必要があるだけでなく、再利用可能である必要もあります。既存のデータ型と将来追加されるデータ型をサポートするコンポーネントは、大規模なソフトウェア システムの開発プロセスに大きな柔軟性をもたらします。

C#およびJavaでは、「ジェネリック」を使用して、複数のデータ型をサポートする再利用可能なコンポーネントを作成できます。これにより、ユーザーは独自のデータ型に応じてコンポーネントを使用できるようになります。

1. ジェネリックメソッド

TypeScript では、ジェネリック メソッドを宣言する方法が 2 つあります。

関数gen_func1<T>(引数: T): T {
    引数を返します。
}
// または let gen_func2: <T>(arg: T) => T = function (arg) {
    引数を返します。
}

電話をかける方法も 2 つあります。

gen_func1<文字列>('Hello world');
gen_func2('こんにちは世界'); 
// 2 番目の呼び出しメソッドでは、渡されたパラメータに基づいてコンパイラが対応する型を自動的に識別するため、型パラメータを省略できます。

2. ジェネリックとAny

特殊な型Any of Ts 、使用時に任意の型を置き換えることができます。一見すると、この 2 つに違いはないように見えますが、実際は次のようになります。

    // 方法 1: 任意のパラメータを持つメソッド function any_func(arg: any): any {
        console.log(引数の長さ);
    		引数を返します。
    }
     
    // 方法 2: 配列ジェネリックメソッド function array_func<T>(arg: Array<T>): Array<T> {
    	  console.log(引数の長さ);
    		引数を返します。
    }
  • 方法 1 はargパラメータのlength属性を出力します。 any任意の型を置き換えることができるため、渡されたパラメータが配列またはlength属性を持つオブジェクトでない場合、このメソッドは例外をスローします。
  • 方法 2 では、パラメータ型をArrayのジェネリック型として定義します。この型には必ずlengthプロパティがあるため、例外はスローされません。

3. ジェネリック型

汎用インターフェース:

インターフェース Generics_interface<T> {
    (引数: T): T;
}
 
関数 func_demo<T>(引数: T): T {
    引数を返します。
}
 
func1: Generics_interface<number> = func_demo とします。
func1(123); // 正しい型の実際のパラメータ func1('123'); // 間違った型の実際のパラメータ

3.3 カスタム型: インターフェースと型エイリアス

Interface 、中国語ではインターフェースと訳されます。

Type alias 、タイプエイリアス。

1. 類似点

オブジェクトまたは関数を説明するために使用できます。

インターフェース ユーザー {
  名前: 文字列
  年齢: 番号
}
 
タイプ ユーザー = {
  名前: 文字列
  年齢: 番号
};
 
インターフェースSetUser{
  (名前: 文字列、年齢: 数値): void;
}
タイプ SetUser = (名前: 文字列、年齢: 数値): void;

どちらも拡張機能を許可します:

interfacetype両方とも拡張可能であり、両者は互いに独立していません。つまり、 interface extends typeでき、 typeextends interfaceできます。効果は似ていますが、両者の構文は異なります

インターフェースはインターフェースを拡張する

インターフェース名 { 
  名前: 文字列; 
}
インターフェース User は Name を拡張します { 
  年齢: 番号; 
}

型は型を拡張する

タイプ名 = { 
  名前: 文字列; 
}
User = Name & { age: number } と入力します。

インターフェースは型を拡張する

タイプ名 = { 
  名前: 文字列; 
}
インターフェース User は Name を拡張します { 
  年齢: 番号; 
}

型はインターフェースを拡張する

インターフェース名 { 
  名前: 文字列; 
}
タイプ ユーザー = 名前 & { 
  年齢: 番号; 
}

2. 相違点

typeはOKだがinterfaceはダメ

type 、基本型のエイリアス、ユニオン型、タプルなどを宣言できます。

// 基本型エイリアス type Name = string
 
//ユニオン型インターフェース Dog {
    ウォン();
}
インターフェース Cat {
    ミャオ();
}
 
ペットの種類 = 犬 | 猫
 
// 配列内の各位置の型を具体的に定義します type PetList = [Dog, Pet]

typeステートメントでは、 typeofを使用して割り当てるインスタンスの型を取得することもできます。

// 変数の型を取得したい場合はtypeofを使用します
div = document.createElement('div'); とします。
タイプ B = typeof div

その他のトリック

type StringOrNumber = 文字列 | 数値;  
タイプ Text = 文字列 | { テキスト: 文字列 };  
NameLookup = Dictionary<文字列、Person>と入力します。  
型 Callback<T> = (data: T) => void;  
型 Pair<T> = [T, T];  
type Coordinates = Pair<number>;  
Tree<T> = T | { 左: Tree<T>、右: Tree<T> }; と入力します。

interfaceはOKだがtypeはダメ

interfaceマージを宣言できる

インターフェース ユーザー {
  名前: 文字列
  年齢: 番号
}
 
インターフェース ユーザー {
  性別: 文字列
}
 
/*
ユーザーインターフェースは{
  名前: 文字列
  年齢: 番号
  性別: 文字列 
}
*/

interfaceはオプション属性と読み取り専用属性があります

オプション属性

インターフェース内のすべての属性が必須というわけではありません。 特定の条件下でのみ存在するものや、まったく存在しないものもあります。 たとえば、関数に渡されるパラメーター オブジェクトの一部のプロパティにのみ値が割り当てられます。オプション属性を持つインターフェースは、オプション属性名の定義の後に?記号が追加されることを除いて、通常のインターフェース定義と似ています。下記の通り

インターフェース Person {
  名前: 文字列;
  年齢?: 番号;
  性別?: 番号;
}

読み取り専用プロパティ

名前が示すように、このプロパティは書き込み可能ではなく、オブジェクト プロパティの値はオブジェクトが作成された直後にのみ変更できます。 次に示すように、プロパティ名の前にreadonlyを使用すると、読み取り専用プロパティを指定できます。

インターフェース ユーザー {
    読み取り専用ログイン名: 文字列;
    パスワード: 文字列;
}

上記の例は、User オブジェクトが初期化された後は loginName を変更できないことを示しています。

3.4 実装と継承: implements と extends

extends明らかに ES6 のクラス継承ですが、 implement何をするのでしょうか? extendsとどう違うのでしょうか?

implement 、実装する。 C# や Java のインターフェースの基本的な役割と同様に、 TypeScriptでもインターフェースを使用して、クラスが特定の契約に明示的に準拠するように強制できます。

implement の基本的な使い方:

インターフェースIDeveloper {
   名前: 文字列;
   年齢?: 番号;
}
// わかりました
クラス dev は IDeveloper を実装します {
    名前 = 'アレックス';
    年齢 = 20;
}
// わかりました
クラスdev2はIDeveloperを実装します{
    名前 = 'アレックス';
}
// エラー
クラスdev3はIDeveloperを実装します{
    名前 = 'アレックス';
    年齢 = '9';
}

そして、 extends親クラスを継承し、この 2 つは実際には互換的に使用できます。

クラスAはBを拡張し、C、D、Eを実装する

interfacetypeの使用法は次のとおりです。

3.5 宣言ファイルと名前空間:declareとnamespace

先ほど、Vue プロジェクトのshims-tsx.d.tsshims-vue.d.tsについて説明しました。初期の内容は次のとおりです。

// シムス-tsx.d.ts
Vue をインポートします。{ VNode } から 'vue';
 
グローバル宣言 {
  名前空間 JSX {
    // tslint: 空のインターフェースを無効にする
    インターフェース Element は VNode を拡張します {}
    // tslint: 空のインターフェースを無効にする
    インターフェース ElementClass は Vue {} を拡張します。
    インターフェースIntrinsicElements {
      [要素: 文字列]: 任意;
    }
  }
}
 
// shims-vue.d.ts
モジュール '*.vue' を宣言します。
  'vue' から Vue をインポートします。
  デフォルトの Vue をエクスポートします。
}

declare : サードパーティのライブラリを使用する場合、対応するコード補完、インターフェースプロンプト、その他の機能を取得するには、その宣言ファイルを参照する必要があります。

よく使われるものをいくつか紹介します。

varを宣言するとグローバル変数が宣言されます
宣言関数はグローバルメソッドを宣言します
宣言クラスはグローバルクラスを宣言します
宣言enumはグローバル列挙型を宣言します
グローバル変数を宣言する
モジュールを宣言する

namespace : 「内部モジュール」は「名前空間」と呼ばれるようになりました

module X {これは現在推奨されている構文namespace X {と同等です。 namespace X {

他のJSライブラリとの連携

モジュールと同様に、名前空間を使用する他の JS ライブラリの.d.tsファイルの宣言ファイルも作成できます。たとえば、 D3 JS ライブラリの場合、次のような宣言ファイルを作成できます。

名前空間D3を宣言する{
    エクスポートインターフェースセレクター{...}
}
var d3: D3.Base を宣言します。

つまり、上記の 2 つのファイルは次のようになります。

  • shims-tsx.d.tsバッチは、グローバル変数globalのいくつかの内部モジュールに名前を付けます。
  • shims-vue.d.ts *.vueサフィックスを持つファイルをvueモジュールに渡して処理できることをTypeScript伝えることを意味します。

3.6 アクセス修飾子: private、public、protected

実のところ、理解するのはとても簡単です。

  1. デフォルトはpublicです
  2. メンバーがprivateとしてマークされている場合、そのメンバーは宣言されているクラスの外部からアクセスすることはできません。次に例を示します。
クラス動物{
    プライベート名: 文字列;
    コンストラクター(theName: 文字列) {
        this.name = 名前;
    }
}
 
let a = new Animal('Cat').name; // エラー、'name' はプライベートです

protectedprivateに似ていますが、 protectedメンバーは派生クラスでアクセスできます。

クラス動物{
    保護された名前: 文字列;
    コンストラクター(theName: 文字列) {
        this.name = 名前;
    }
}
 
クラスRhinoはAnimalを拡張します{
    コンストラクタ() {
        スーパー('Rhino');
   }         
   取得名() {
       console.log(this.name) //ここでの名前はAnimalクラスの名前です
   }
}

3.7 オプション パラメーター (?:) と非 Null アサーション演算子 (!.)

オプションパラメータ

関数buildName(firstName: 文字列、lastName?: 文字列) {
    firstName + ' ' + lastName を返す
}
 
// エラーのデモンストレーション buildName("firstName", "lastName", "lastName")
// buildName("firstName") の正しいデモンストレーション
// buildName("firstName", "lastName") の正しいデモンストレーション

非 null アサーション演算子:

変数値が確実に空でないことが確実な場合に使用します。

オプション パラメータとは異なり、非 null アサーション演算子は null または undefined から保護しません。

let s = e!.name; // e が null でないことをアサートし、name プロパティにアクセスします

拡大する

1. 属性またはパラメータで使用しますか? : 属性またはパラメータがオプションであることを示します

2. 属性またはパラメータで ! を使用します。 : 強制解析を示します(TypeScript コンパイラにここに値が必要であることを伝えます)。一般的に vue-decorator の @Prop で使用されます。

3. after 変数を使用してください。 : 型推論でnullとundefinedが除外されることを示します

4. VueコンポーネントのTs記述

vue2.5 以降、vue は ts をより適切にサポートするようになりました。公式ドキュメントによると、TypeScript と組み合わせて Vue を記述する方法は 2 つあります。

Vue.extend

 'vue' から Vue をインポートします
 
  const コンポーネント = Vue.extend({
  	// 型推論が有効
  })

vue クラス コンポーネント

'vue-property-decorator' から { Component, Vue, Prop } をインポートします。
 
@成分
デフォルトのクラスTestをエクスポートし、Vueを拡張します。
  @Prop({ 型: オブジェクト })
  プライベートテスト: { 値: 文字列 }

理想的には、 Vue.extendを書く方法が最も簡単に習得できます。既存の書き込み方法に基づくと、移行コストはほぼゼロになります。

ただし、 Vue.extendモードはmixinsと組み合わせて使用​​する必要があります。ミックスインで定義されたメソッドはTypeScriptでは認識されません

つまり、コードヒントの欠落、型チェック、コンパイルエラーなどの問題が発生します。

選択をするのは新人だけであり、大物は最善のものを選ぶ。 2番目について直接話しましょう:

4.1 vueクラスコンポーネント

画像-20190613013846506

src/components/HelloWorld.vueに戻りましょう。

<テンプレート>
  <div class="hello">
    <h1>{{ メッセージ }}</h1>
    <!-- 省略 -->
  </div>
</テンプレート>
 
<script lang="ts">
'vue-property-decorator' から { Component, Prop, Vue } をインポートします。
 
@成分
デフォルトのクラスHelloWorldをエクスポートし、Vueを拡張します。
  @Prop() プライベートメッセージ!: 文字列;
}
</スクリプト>
 
<!-- CSS をこのコンポーネントのみに制限するために "scoped" 属性を追加します -->
<スタイル スコープ></style>

pythonを書いたことがある学生には馴染みがあるはずです:

公式にサポートされているライブラリであるvue-property-decorator関数デコレータ構文を提供します。

1. 関数修飾子@

「@」は関数の変更というよりも、変更する関数への参照または呼び出しです。

あるいは、平易な言葉で言うと: @ : 「以下は私に囲まれています。」

たとえば、次のコードには呼び出されないが出力結果も生成する 2 つの関数があります。

テスト(f){
    console.log("前...");
    f()
		console.log("後...");
 }
 
@テスト
関数(){
	console.log("func が呼び出されました");
}

直接実行して結果を出力します。

前に ...
funcが呼び出されました
後 ...

上記のコードから、次のことがわかります。

  • 定義されている関数はtestfunc 2 つだけですが、これらは呼び出されません。
  • @test がなければ、実行しても出力は生成されません。

ただし、インタープリターが関数修飾子「@」を読み取る場合、次の手順が実行されます。

  1. test関数を呼び出すには、 test関数のエントリ パラメーターは " func " という関数です。
  2. test関数が実行され、エントリパラメータ(つまり、 func関数)が呼び出されます(実行されます)。

つまり、修飾子を持つ関数のエントリ パラメータは、以下の関数全体になります。これは、 JavaScripfunction a (function () { ... });少し似ています。

2. vue-property-decoratorvuex-classが提供するデコレータ

vue-property-decoratorのデコレータ:

  • @プロップ
  • プロップシンク
  • @提供する
  • @モデル
  • @時計
  • @注入
  • @提供する
  • @エミット
  • @Component (vue-class-component によって提供)
  • ミックスイン(vue-class-component が提供する mixins というヘルパー関数)

vuex-classデコレータ:

  • @州
  • @ゲッター
  • @アクション
  • @突然変異

元の Vue コンポーネント テンプレートを見てみましょう。

'@/components' から {componentA,componentB} をインポートします。
 
エクスポートデフォルト{
	コンポーネント: { コンポーネントA、コンポーネントB}、
	小道具: {
    propA: { 型: 数値 },
    propB: { デフォルト: 'デフォルト値' },
    propC: { 型: [文字列、ブール値] },
  }
  // コンポーネントデータ data() {
    戻る {
      メッセージ: 'こんにちは'
    }
  },
  // 計算プロパティ computed: {
    逆メッセージ(){
      this.message.split('').reverse().join('') を返します
    }
    // Vuexデータステップ() {
    	this.$store.state.count を返します
    }
  },
  メソッド: {
    メッセージの変更 () {
      this.message = "さようなら"
    },
    取得名() {
    	name = this.$store.getters['person/name']とします。
    	戻り名
    }
  },
  // ライフサイクルが作成されました () { },
  マウントされた(){}、
  更新されました () { },
  破壊されました () { }
}

上記のテンプレートは、修飾子の記述ルールに置き換えられます。

'vue-property-decorator' から { Component, Vue, Prop } をインポートします。
'vuex-class' から { State, Getter } をインポートします。
'@/person' から { count, name } をインポートします
'@/components' から {componentA, componentB } をインポートします。
 
@成分({
    コンポーネント:{コンポーネントA、コンポーネントB},
})
デフォルトのクラスHelloWorldをエクスポートし、Vueを拡張します{
	@Prop(Number) 読み取り専用 propA!: number | undefined
    @Prop({ default: 'デフォルト値' }) 読み取り専用 propB!: 文字列
    @Prop([String, Boolean]) 読み取り専用 propC!: 文字列 | ブール値 | 未定義
  
  // 元のデータ
  メッセージ = 'こんにちは'
  
  // 計算プロパティ private get riversMessage(): string[] {
  	this.message.split('').reverse().join('') を返します
  }
  // Vuex データ @State((state: IRootState) => state . booking. currentStep) step!: number
	@Getter( '人/名前') 名前!: 名前
  
  // 方法
  パブリックchangeMes​​sage(): void {
    this.message = 'さようなら'
  },
  パブリックgetName(): 文字列{
    storeName = 名前とします
    ストア名を返す
  }
	// ライフサイクル private created (): void { },
  プライベートマウント():void { },
  プライベート更新():void { },
  プライベート破棄(): void { }
}

ご覧のとおり、ライフサイクル リストにprivate XXXXメソッドを追加します。これは、他のコンポーネントに公開されるべきではないためです。

methodにプライベート制約を設けない理由は、 @Emitを使用して親コンポーネントに情報を渡すことができるためです。

4.2 グローバルツールの追加

グローバル モジュールを導入するには、 main.ts変更する必要があります。

'vue' から Vue をインポートします。
'./App.vue' からアプリをインポートします。
'./router' からルーターをインポートします。
'./store' からストアをインポートします。
 
Vue.config で productionTip を false に設定します。
 
新しいVue({
  ルーター、
  店、
  レンダリング: (h) => h(App),
}).$mount('#app');

npm i VueI18n

'vue' から Vue をインポートします。
'./App.vue' からアプリをインポートします。
'./router' からルーターをインポートします。
'./store' からストアをインポートします。
// 新しいモジュール import i18n from './i18n';
 
Vue.config で productionTip を false に設定します。
 
新しいVue({
    ルーター、 
    店、 
    i18n, // 新しいモジュールのレンダリング: (h) => h(App),
}).$mount('#app');

しかし、これだけでは十分ではありません。 src/vue-shim.d.tsを移動する必要があります:

//グローバルメソッドを宣言する。declare module 'vue/types/vue' {
  インターフェースVue {
        読み取り専用 $i18n: VueI18Next;
        $t: 翻訳関数;
    }
}

後でthis.$i18n()を使用すると、エラーは報告されません。

4.3 Axiosの使用とパッケージング

Axiosパッケージは人によって用途が異なります

TSでAxiosの使用を体験したいだけの場合は、 vue-axiosをインストールしてAxiosを使用することができます。

$ npm i axios vue-axios

main.tsに追加:

'vue' から Vue をインポートします
'axios' から axios をインポートします
'vue-axios' から VueAxios をインポートします
 
Vue.use(VueAxios、axios) を使用します

次に、それをコンポーネントで使用します。

Vue.axios.get(api).then((レスポンス) => {
  コンソールログ(応答データ)
})
 
this.axios.get(api).then((レスポンス) => {
  コンソールログ(応答データ)
})
 
this.$http.get(api).then((レスポンス) => {
  コンソールログ(応答データ)
})

1. 新しいファイルrequest.tsを作成する

ファイルディレクトリ:

-api
    - main.ts // 実際に -utils を呼び出す
    - request.ts // インターフェースのカプセル化

2. request.tsファイルの解析

'axios' から * を axios としてインポートします。
'@/store' からストアをインポートします。
// これは、使用される特定の UI コンポーネント ライブラリに応じて置き換えることができます。import { Toast } from 'vant';
'axios' から { AxiosResponse、AxiosRequestConfig } をインポートします。
 
 /* baseURL は実際のプロジェクトに応じて定義されます */
定数 baseURL = process.env.VUE_APP_URL;
 
 /* axiosインスタンスを作成する */
const サービス = axios.default.create({
    ベースURL、
    timeout: 0, // リクエストタイムアウト maxContentLength: 4000,
});
 
service.interceptors.request.use((config: AxiosRequestConfig) => {
    設定を返します。
}, (エラー: 任意) => {
    Promise.reject(エラー);
});
 
サービスインターセプターレスポンスの使用(
    (レスポンス: AxiosResponse) => {
        応答ステータスが 200 の場合
            Toast.fail('リクエストエラー!');
        } それ以外 {
            応答データを返します。
        }
    },
    (エラー: 任意) => {
        Promise.reject(error) を返します。
    });
    
デフォルト サービスをエクスポートします。

便宜上、axios によって返される固定形式を定義し、新しいajax.tsを作成する必要もあります。

エクスポートインターフェースAjaxResponse {
    コード: 番号;
    データ: 任意;
    メッセージ: 文字列;
}

3. main.tsインターフェース呼び出し:

// api/main.ts
'../utils/request' からリクエストをインポートします。
 
// 得る
エクスポート関数 getSomeThings(params:any) {
    リクエストを返す({
        URL: '/api/getSomethings',
    });
}
 
// 役職
エクスポート関数 postSomeThings(params:any) {
    リクエストを返す({
        url: '/api/postSomethings',
        メソッド: 'post'、
        データ:パラメータ
    });
}

5. コンポーネントを書く

時間を節約するために、 src/components/HelloWorld.vueブログ投稿コンポーネントに置き換えてみましょう。

<テンプレート>
	<div class="blogpost">
		<h2>{{ 投稿.タイトル }}</h2>
		<p>{{ post.body }}</p>
		<p class="meta">{{ post.author }} が {{ date } に書いたもの } </p>
	</div>
</テンプレート>
 
<script lang="ts">
'vue-property-decorator' から { Component, Prop, Vue } をインポートします。
 
// ここでデータを制限します export interface Post {
	タイトル: 文字列;
	本文: 文字列;
	著者: 文字列;
	投稿日: 日付;
}
 
@成分
デフォルトのクラスHelloWorldをエクスポートし、Vueを拡張します。
	@Prop() プライベート投稿!: 投稿;
 
	日付を取得する() {
		`${this.post.datePosted.getDate()}/${this.post.datePosted.getMonth()}/${this.post.datePosted.getFullYear()}` を返します。
	}
}
</スクリプト>
 
<スタイルスコープ>
h2 {
  テキスト装飾: 下線;
}
p.meta {
  フォントスタイル: 斜体;
}
</スタイル>

次に、 Home.vueで使用します。

<テンプレート>
  <div class="home">
    <img alt="Vue ロゴ" src="../assets/logo.png">
   	<HelloWorld v-for="blogPosts 内の blogPost" :post="blogPost" :key="blogPost.title" />
  </div>
</テンプレート>
 
<script lang="ts">
'vue-property-decorator' から Component、Vue } をインポートします。
import HelloWorld, { Post } from '@/components/HelloWorld.vue'; // @ は /src へのエイリアスです
 
@成分({
  コンポーネント:
    こんにちは世界、
  },
})
デフォルトクラスHomeをエクスポートし、Vueを拡張します。
    プライベートブログ投稿: Post[] = [
        {
          タイトル: 「初めてのブログ投稿です!」
          本文: 'Lorem ipsum dolor sit amet.',
          著者: 'エルケ'、
          投稿日: 新規日付(2019, 1, 18)
        },
        {
          タイトル: 「見てよ、私はブログを書いているのよ!」
          本文: 'やったー、これが2回目の投稿だ!',
          著者: 'エルケ'、
          投稿日: 新規日付(2019, 1, 19)
        },
        {
          タイトル: 「またひとつ?!」
          本文: 'もう一つ!',
          著者: 'エルケ'、
          投稿日: 新規日付(2019, 1, 20)
        },
      ];
}
</スクリプト>

次にプロジェクトを実行します。

これは単純な親子コンポーネントです。

Class APIの撤回に関しては、実はかなり快適です。 classを使用してVueコンポーネントを記述するのは非常に奇妙です。 (そのため、 Ts入門のこの記事ではClass APIは一切説明していません)

以上が、Vue の新しいパートナー TypeScript のクイックスタート実践の詳しい内容です。Vue TypeScript クイックスタートの詳細については、123WORDPRESS.COM の他の関連記事にも注目してください。

以下もご興味があるかもしれません:
  • TypeScript 基本チュートリアル: トリプルスラッシュ命令
  • Vue プロジェクトで TS (TypeScript) を使用するための入門チュートリアル
  • Vue 3.0 以前の TypeScript ベストプラクティスの詳細な説明
  • TypeScript 入門 - インターフェース
  • TypeScript 基本データ型
  • TypeScript 入門

<<:  MySQL 8.0.11 のインストールと設定方法のグラフィック チュートリアル (win10)

>>:  Centos7でのSambaサーバー構成(実戦)

推薦する

Centos7にnginxをインストールする方法

必要な環境をインストールする1. gccのインストールnginx をインストールするには、公式サイト...

CentOS 6 または CentOS 7 でディスク領域をクリアする方法

以下は、CentOS 6 または CentOS 7 サーバーのディスク領域をクリアするための簡単なコ...

MySQL 8.0.20 圧縮版のインストールチュートリアル(画像とテキスト付き)

1. MySQL ダウンロード アドレス。 http://ftp.ntu.edu.tw/MySQL...

Mysqlツリー再帰クエリの実装方法

序文部門テーブルなどのデータベース内のツリー構造データの場合、部門のすべての従属部門または部門のすべ...

MySQL 8.0.23 インストールの超詳細なチュートリアル

目次序文1. 公式サイトからMySQLをダウンロードする2. 解凍ファイルを設定する3. 初期化4....

HTML テーブル境界コントロールの詳細な説明

上の境界線のみを表示する <table frame=above>下の境界線のみを表示する...

Linux スワップ パーティション (詳細説明)

目次リナックス1. SWAPとは2. swappiness は何を調節しますか? 3. スワップ操作...

JS の toFixed() メソッドの丸め精度の問題の詳細な説明

目次落とし穴充填方法何の穴ですか?要約する落とし穴最近、仕事で商品の割引価格を計算すると、いつも1セ...

CSS3で作られたレインボーボタンスタイル

結果: 実装コード: html <div class="buttons"&...

HTML で自動ページジャンプを実現する 5 つの方法

前回の記事では、HTML ページが 3 秒後に自動的にジャンプする一般的な 3 つの方法を紹介しまし...

XHTML 3つの文書型宣言

XHTML は 3 つのドキュメント タイプ宣言を定義します。最もよく使用されるのは XHTML T...

2 つの MySQL ユーザー削除ステートメント (delete user と drop user) の違い

ヒント: MySQL では、ユーザーの作成と削除が頻繁に必要になります。ユーザーを作成するときは、通...

Raspberry Pi 4 に Ubuntu 19.10 をインストールするための詳細なチュートリアル

以前、raspbian で実行したときに opencv の一部の依存関係をパッケージ化できず、一部の...

MySQL 8.0 の新機能 - 管理ポートの使用の概要

目次序文接続管理追加の接続管理ポート要約する序文皆さんの多くは、次のようなエラー メッセージに遭遇し...

MySQLの日付文字列タイムスタンプ変換の詳細な説明

時刻、文字列、タイムスタンプ間の変換は、日常生活でよく使用されます。よく使用されますが、私は使用する...