一,前言
繼續學習
二,TS接口泛型自定義類型
1.接口
TypeScript 接口(Interface)是一種定義對象形狀的強大工具,它可以描述對象必須包含的屬性、方法和它們的類型。接口不會被編譯成 JavaScript 代碼,僅在編譯階段用于類型檢查。
基本語法與用法
接口使用 interface
關鍵字定義,下面是一些常見用法:
// 定義基本接口
interface User {name: string;age: number;//“?” 表明該屬性是可選的,其數據類型為布爾型(即值只能是 true 或 false)。“readonly id: string;” 表示定義一個名為 “id” 的屬性,“readonly” 關鍵字意味著這個屬性一旦被賦值就不能再被修改isAdmin?: boolean; // 可選屬性readonly id: string; // 只讀屬性greet: (message: string) => void; // 方法
}// 使用接口
const user: User = {name: "張三",age: 30,id: "user123",greet: (message) => console.log(`${message}, ${this.name}`)
};// 接口繼承
interface AdminUser extends User {role: string;
}// 函數接口
interface Calculator {(a: number, b: number): number;
}const add: Calculator = (a, b) => a + b;// 可索引接口
interface StringArray {[index: number]: string;
}const names: StringArray = ["Alice", "Bob"];
高級特性
接口還支持更復雜的類型定義:
// 混合類型接口(對象 + 函數)
interface Counter {(): void; // 函數簽名count: number; // 屬性
}function createCounter(): Counter {const counter = () => counter.count++;counter.count = 0;return counter;
}// 接口合并(同名接口會自動合并)
interface Box {height: number;
}interface Box {width: number;
}const box: Box = { height: 10, width: 20 };
最佳實踐
- 使用接口定義對象形狀,特別是在大型項目中
- 使用類型別名處理聯合類型、交叉類型等復雜類型
- 保持接口名稱簡潔明了,通常使用名詞或形容詞 + 名詞
- 為可選屬性添加
?
標記,為只讀屬性添加readonly
標記
接口是 TypeScript 類型系統的核心組成部分,合理使用可以顯著提高代碼的可讀性和可維護性。
2.泛型
泛型是 TypeScript 中一個強大的特性,它允許我們創建可重用的組件,同時保持類型安全。泛型讓我們可以在定義函數、接口或類時不預先指定具體類型,而是在使用時再確定類型。
基本泛型函數:
// 泛型函數示例
function identity<T>(arg: T): T {return arg;
}// 使用泛型函數
const output1 = identity<string>("myString"); // 顯式指定類型
const output2 = identity(100); // 類型推斷為 number
泛型接口:
// 泛型接口
interface GenericIdentityFn<T> {(arg: T): T;
}function identity<T>(arg: T): T {return arg;
}const myIdentity: GenericIdentityFn<number> = identity;
泛型類:
// 泛型類
class GenericNumber<T> {zeroValue: T;add: (x: T, y: T) => T;
}const myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = (x, y) => x + y;
3,自定義類型
自定義類型允許我們創建復雜的、特定用途的類型定義,提高代碼的可讀性和類型安全性。
類型別名(Type Aliases):
// 基本類型別名
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;// 復雜類型別名
type UserInfo = {name: string;age: number;address?: string;
};// 泛型類型別名
type Container<T> = { value: T };
交叉類型(Intersection Types):
// 交叉類型
interface Colorful {color: string;
}interface Circle {radius: number;
}type ColorfulCircle = Colorful & Circle;const cc: ColorfulCircle = {color: "red",radius: 10
};
聯合類型
// 聯合類型
type StringOrNumber = string | number;
type Text = string | { text: string };// 字面量類型
type Easing = "ease-in" | "ease-out" | "ease-in-out";
**條件類型
// 條件類型
type MessageOf<T> = T extends { message: unknown } ? T["message"] : never;interface Email {message: string;
}type EmailMessageContents = MessageOf<Email>; // string
映射類型
// 映射類型
interface User {name: string;age: number;email: string;
}// 創建只讀版本
type ReadonlyUser = {readonly [P in keyof User]: User[P];
};// 創建可選版本
type PartialUser = {[P in keyof User]?: User[P];
};
三,v-for指令
v-for
是 Vue.js 中用于循環渲染列表的指令,它允許你基于數組或對象的數據來動態生成 DOM 元素。
基本用法
v-for
指令的基本語法是 item in items
,其中 items
是源數據數組,而 item
是當前被迭代的數組元素的別名。
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>Vue v-for 簡單示例</title><script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script><style>body { font-family: Arial, sans-serif; }.example { margin-bottom: 30px; padding: 15px; border: 1px solid #eee; }ul { list-style-type: none; padding: 0; }li { margin: 5px 0; }</style>
</head>
<body><div id="app"><!-- 示例1:循環數組 --><div class="example"><h3>1. 循環數組</h3><ul><li v-for="(item, index) in fruits" :key="index">{{ index + 1 }}. {{ item }}</li></ul></div><!-- 示例2:循環對象 --><div class="example"><h3>2. 循環對象</h3><ul><li v-for="(value, key) in user" :key="key">{{ key }}: {{ value }}</li></ul></div><!-- 示例3:循環數字 --><div class="example"><h3>3. 循環數字</h3><p>前 {{ count }} 個數字的平方:</p><ul><li v-for="n in count" :key="n">{{ n }} × {{ n }} = {{ n * n }}</li></ul></div></div><script>new Vue({el: '#app',data: {fruits: ['蘋果', '香蕉', '橙子', '草莓'],user: {name: '張三',age: 28,email: 'zhangsan@example.com'},count: 5}})</script>
</body>
</html>
- key 的重要性:
- 為每個 v-for 項提供唯一的 key 是最佳實踐,它幫助 Vue 跟蹤節點的身份,從而高效地更新 DOM。
- 避免使用索引作為 key,特別是當列表可能會重新排序或過濾時,這可能導致性能問題或錯誤的更新。
- 響應式更新:
- Vue 能夠檢測到數組的變更方法(如 push、pop、splice 等)并觸發相應的 DOM 更新。
- 直接修改數組索引或長度不會觸發響應式更新,應使用 Vue 提供的方法。
- 過濾和排序:
- 當需要顯示過濾或排序后的結果時,應使用計算屬性或方法,而不是在 v-for 中直接操作。
四,props
props
是 Vue 組件中用于從父組件向子組件傳遞數據的機制。它允許你創建可復用的組件,同時保持數據的單向流動。
index.ts
// 定義一個接口,用于限制person對象的具體屬性
export interface PersonInter
{name: string;age: number;sex: string;
}// 一個自定義類型
export type Persons = PersonInter[]
App.vue
<template><person a="hh":list="personlist"/>
</template>
<script lang="ts" setup name="App">
import person from './components/person.vue';
import { reactive } from 'vue';
import { type Persons} from './types';
let personlist = reactive<Persons>([{name:'張三',age:18,sex:'男',},{name:'李四',age:19,sex:'男',},{name:'王五',age:20,sex:'男'},])
</script>
person.vue
<template><div class="person"><h2>{{a}}</h2>
<ul><li v-for="p in list" :key="p.id">{{p.name}} {{p.age}}</li>
</ul></div>
</template>
<script lang="ts" setup name="Person">
import { defineProps } from 'vue';
// // 接收a參數和list
defineProps(['a','list'])
// // 接收a參數,同時將props保存起來
// let x = defineProps(['a'])
// console.log(x.a)
</script>
<style></style>
大概就是這樣,反正就是從父組件那里搞點數據,還有很多別的用法遇到了再說。