<!-- * @Description: vue-property-decorator語法 vue-class-component語法 TS語法 * @Version: 2.0 * @Autor: lhl * @Date: 2020-08-27 14:33:43 * @LastEditors: lhl * @LastEditTime: 2020-08-28 14:55:24 -->
<template>
<div class="hello">
<!-- props的數據 -->
<h1>{{ msg }}</h1>
<!-- 變量的使用 -->
<p>{{ dataMsg }} -- 初始值undefined:{{testMsg}}</p>
<!-- 組件的使用 -->
<About/>
<!-- 事件調用 -->
<button v-on:click="hello">Click點我啊</button>
<!-- ref使用 -->
<input ref="input">
<p>傳過來的數據數字類型{{count}}----名字字符串必定有值:{{name}}----布爾值:{{flag}}</p>
<p>計算屬性:{{newMsg}}</p>
</div>
</template>
<script lang="ts"> import { Component, Prop, Vue, Watch } from "vue-property-decorator"; import About from "@/views/About.vue"; // 導入組件 // import { mapGetters, mapActions } from "vuex" // vuex模塊
// 跟多使用方法api請移步:https://www.npmjs.com/package/vue-property-decorator
/* ts 特殊符號用法 1. 屬性或參數中使用 ?:表示該屬性或參數為可選項 2. 屬性或參數中使用 !:表示強制解析(告訴typescript編譯器,這里一定有值),常用於vue-decorator中的@Prop 3. 變量后使用 !:表示類型推斷排除null、undefined */
// 裝飾器用法
@Component({ // 注冊組件
components: { About } // computed: mapGetters([
// 'xx'
// ]),
// methods: mapActions([
// 'xx'
// ])
}) // Prop等價於 // props: { // msg: { // type: String // } // count: { // type: Number, // }, // name: { // default: 'default value', // }, // addr: { // type: [String, Boolean], // }, // },
export default class HelloWorld extends Vue { @Prop() private msg!: string; @Prop(Number) readonly count: number | undefined @Prop({ default: 'default value' }) readonly name!: string @Prop([String, Boolean]) readonly flag: string | boolean | undefined $refs!: { input: HTMLInputElement } dataMsg = "這就相當於vue + js的data里面的數據"; // 請注意,如果這里直接聲明初始值為undefined,則class屬性不會是反應性的 為了避免這種情況,您可以使用null,value或使用datahook來代替(如下);
personObj = { name: 'ts', age: 1 } // data hook初始化值
data(){ return { testMsg: undefined } } // 監聽事件 immediate: true 初始化加載一次 deep: true 對象深度監聽
@Watch('personObj.name', {immediate: true, deep: true}) onChangeValue(val:string){ // todo...
console.log('watch里面的數據:' + val) // ts
} // 計算屬性
get newMsg(){ return '你好Ts' + this.dataMsg } // 彈出 Hello World!
hello() { alert("Hello World!") } created() { console.log("created-1") } // Declare mounted lifecycle hook 生命周期
mounted() { console.log("mounted-2") this.$refs.input.focus() } } </script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
</style>
<!-- * @Description: ts語法測試 * @Version: 2.0 * @Autor: lhl * @Date: 2020-08-28 09:10:28 * @LastEditors: lhl * @LastEditTime: 2020-08-28 17:52:22 -->
<template>
<div class="ts-contanter">
<div>hello TS</div>
<p>{{msg}}</p>
<p>{{fullName}}</p>
</div>
</template>
<script lang="ts">
// 概念:ts是js的超集 // 特點:提供類型系統和es6的支持 // 優點: // 增加代碼的可讀性和可維護性 // 在編譯階段就發現錯誤,比運行時發現錯誤好 // 增加了編輯器和ide的功能,代碼不全、接口提示、跳轉到定義、重構 // 包容性、js文件可重命名為.ts文件 // 不顯式的定義類型,也能自動作出類型推論、可定義一切類型、即使typescript編譯報錯,也可生成js文件 // 兼容第三方庫,即使第三方庫不是用ts寫的,也可編寫單獨的類型文件供ts讀取 // 缺點:集成到構建流程需要工作量,可能和一些庫結合的不是很完美 // 安裝:npm i -g typescript 執行tsc ts文件來編譯會生成js文件或者ide支持
// 聲明文件 // declare var 聲明全局變量 // declare function 聲明全局方法 // declare class 聲明全局類 // declare enum 聲明全局枚舉類型 // declare namespace 聲明(含有子屬性的)全局對象 // interface 和 type 聲明全局類型 // export 導出變量 // export namespace 導出(含有子屬性的)對象 // export default ES6 默認導出 // export = commonjs 導出模塊 // export as namespace UMD 庫聲明全局變量 // declare global 擴展全局變量 // declare module 擴展模塊 /// 三斜線指令
import { Component, Vue } from "vue-property-decorator"; // 接口使用的一般場景
interface Person { readonly x: number; // 只讀屬性
firstName: string; lastName: string; [propName: string]: any; //定義了任意屬性,取 string 類型,屬性值取any類型
age?: number; // 設為可選屬性
year: number | string; } // 接口描述一個數字數組
interface NumberArray { [index: number]: number; //只要 index 的類型是 number,那么值的類型必須是 number。
} // 接口繼承 分接口繼承接口 接口繼承類
interface Animal { move(): void; } // 如果需要繼承多個 用逗號隔開
interface Human extends Animal { name: string; age: number; } // 泛型約束
interface Lengthwise { length: number; } @Component // TsGrammerTest文件名開頭需要大寫
export default class TsGrammerTest extends Vue { msg = "初始值"; fullName = "mr"; created() { this.msg = this.getName("bobo"); const obj = { firstName: "lan", lastName: "tian", gender: "male", x: 8, year: "2018" }; this.fullName = this.getFullName(obj); } mounted() { let arr1: number[] = [1, 2, 3]; //數組的值只能是number類型
let arr2: any[] = ["xiao ming", 11, false]; //數組的值可以是任意類型
let arr3: NumberArray = [4, 5, 6, 7, 8]; // 接口描述數組類型
let arr4: ReadonlyArray<number> = arr1; // TypeScript具有ReadonlyArray<T>類型 確保數組創建后再也不能被修改 console.log(arr4[0] = 12) 報錯
console.log(arr1, arr2, arr3, arr4); // 接口繼承接口
let person: Human = { age: 18, name: "Jack", move() { console.log("move"); } }; console.log(person,'person',person.move()); // 泛型在調用時候才知道類型 或者 可以使用斷言
let output1 = this.anyType<string>("哈哈String"); // type of output will be 'string'
console.log(output1,'output1') // 泛型約束
let output2 = this.loggingIdentity({length: 10, value: 3}); console.log(output2,'output2') } // 泛型使用規則:你必須把這些參數當做是任意或所有類型 也可以使用不同的泛型參數名,只要在數量上和使用方式上能對應上就可以
anyType<T>(arg: T): T { return arg; } // 泛型約束
loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length,'arg長度'); // Now we know it has a .length property, so no more error
return arg; } // 函數用法 person: string = 'Tom' 參數默認值, age ?: number 可選參數 , ...items: any[] 剩余參數
getName(person: string) { return "Hello, " + person; } // interface 用法
getFullName(person: Person) { return "Hello, " + person.firstName + " " + person.lastName + person.gender; } } </script>