vue中ts是指typescript文件,typescript是js超集,它最主要做的一件事,就是數(shù)據(jù)類型驗證;ts是微軟開發(fā)的,適用于大型的項目開發(fā),能使開發(fā)更加嚴謹。
本教程操作環(huán)境:Windows10系統(tǒng)、Vue 3版、DELL G3電腦
vue中ts是什么文件?
vue中TS的應用
TS(typescript)
ts: typescript ,它是js超集(包含js所有的語法,在基礎(chǔ)上增加了數(shù)據(jù)類型定義) 它最主要做的一件事,就是數(shù)據(jù)類型驗證。 js是弱類型語言,java是強類型語言 let a = 123,a 就是number類型。let a = '123',a就是字符串類型 但是ts是在聲明并定義的時候就是定義了它的數(shù)據(jù)類型。 let a:number = 100 如果你要去修改a ,a只能被修改成數(shù)值型,如果你修改成其他類型,那么會報錯。 它運行的時候并不會報錯(即使數(shù)據(jù)類型有問題,但是結(jié)果不會出錯),在編譯的過程中會報錯。 瀏覽器沒有辦法去解析ts,ts是來源于js最終還是要以js的狀態(tài)去運行。ts是弱類型,它也標志著,ts去向java靠攏 ts是誰開發(fā)的? 是微軟開發(fā)的 ts適用的場景? 它適用于大型的項目開發(fā),使你的開發(fā)更加的嚴謹 誰在用ts? 15年angular2.x它就是開始使用ts,所以說angular是谷歌和微軟開發(fā)的精品。 15之前大家都是使用angular(1.x),它的設(shè)計模式還是MVC。它在升級到2.x時候,全變了,從語法到設(shè)計模式都換了。它換成MVVM設(shè)計模式 vue3.0(核心庫,還是載測試版本)它的源碼就是用ts 一線大廠做項目都用ts。比如vue最新腳手架+ ts 或者 react中 ts + dva +umi+hook
登錄后復制
一、安裝
npm install -g typescript Version 4.2.3
登錄后復制
二、查看版本
tsc --version
登錄后復制
三、運行文件(手動)
tsc 文件名
登錄后復制
四、自動運行文件
- 先生成配置文件
tsc --init 它會自動創(chuàng)建出tsconfig.json文件
登錄后復制
- 設(shè)置終端監(jiān)聽
vscode => 終端=> 運行生成任務 => 選擇監(jiān)聽 (開啟自動監(jiān)聽模式)
登錄后復制
- tsconfig.json
釋放出,輸出目錄,目錄地址隨意設(shè)置 "outDir": "./dist",
登錄后復制
{"compilerOptions": { /* 基本選項 */ "target": "es5",// 指定 ECMAScript 目標版本: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT' "module": "commonjs",// 指定使用模塊: 'commonjs', 'amd', 'system', 'umd' or 'es2015' "lib": [],// 指定要包含在編譯中的庫文件 "allowJs": true,//允許編譯 javascript 文件 "checkJs": true,//報告javascript文件中的錯誤 "jsx": "preserve",//指定jsx代碼的生成: 'preserve', 'react-native', or 'react' "declaration": true,//生成相應的 '.d.ts' 文件 "sourceMap": true, //生成相應的 '.map' 文件 "outFile": "./",//將輸出文件合并為一個文件 "outDir": "./",//指定輸出目錄 "rootDir": "./",//用來控制輸出目錄結(jié)構(gòu) --outDir. "removeComments": true,//刪除編譯后的所有的注釋 "noEmit": true,//不生成輸出文件 "importHelpers": true,//從tslib導入輔助工具函數(shù) "isolatedModules": true,//將每個文件做為單獨的模塊(與 'ts.transpileModule' 類似). /* 嚴格的類型檢查選項 */ "strict": true,//啟用所有嚴格類型檢查選項 "noImplicitAny": true,//在表達式和聲明上有隱含的any類型時報錯 "strictNullChecks": true,//啟用嚴格的null檢查 "noImplicitThis": true,//當this表達式值為 any 類型的時候,生成一個錯誤 "alwaysStrict": true,//以嚴格模式檢查每個模塊,并在每個文件里加入 'use strict' /* 額外的檢查 */ "noUnusedLocals": true,//有未使用的變量時,拋出錯誤 "noUnusedParameters": true,//有未使用的參數(shù)時,拋出錯誤 "noImplicitReturns": true,//并不是所有函數(shù)里的代碼都有返回值時,拋出錯誤 "noFallthroughCasesInSwitch": true,//報告switch語句的fallthrough錯誤。 /* 模塊解析選項 */ "moduleResolution": "node",//選擇模塊解析策略:'node' (Node.js) or 'classic' (TypeScript pre-1.6) "baseUrl": "./",//用于解析非相對模塊名稱的基目錄 "paths": {},//模塊名到基于 baseUrl 的路徑映射的列表 "rootDirs": [],//根文件夾列表,其組合內(nèi)容表示項目運行時的結(jié)構(gòu)內(nèi)容 "typeRoots": [],//包含類型聲明的文件列表 "types": [],//需要包含的類型聲明文件名列表 "allowSyntheticDefaultImports": true, //允許從沒有設(shè)置默認導出的模塊中默認導入。 /* Source Map Options */ "sourceRoot": "./",//指定調(diào)試器應該找到 TypeScript 文件而不是源文件的位置 "mapRoot": "./",//指定調(diào)試器應該找到映射文件而不是生成文件的位置 "inlineSourceMap": true,//生成單個 soucemaps 文件,而不是將 sourcemaps 生成不同的文件 "inlineSources": true,//將代碼與 sourcemaps 生成到一個文件中,要求同時設(shè)置了 --inlineSourceMap 或 --sourceMap 屬性 /* 其他選項 */ "experimentalDecorators": true,//啟用裝飾器 "emitDecoratorMetadata": true//為裝飾器提供元數(shù)據(jù)的支持 }}
登錄后復制
注意:有的同學電腦運行有問題,powerShell 權(quán)限的問題
以管理員身份運行 PowerShell,并執(zhí)行命令set-ExecutionPolicy RemoteSigned將PowerShell的執(zhí)行策略更改為RemoteSigned
登錄后復制
五、ts的基本語法
- Number
- String
- Boolean
- Object
- Array
- 元祖
- undefined
- 枚舉
- 任意類型any
//numberlet a:Number = 10//a = '字符串' 這種賦值不對?。?!a =500console.log(a,'a的值')//Stringlet msg:String = '信息'msg = "100"//Booleanlet isShow:Boolean = trueisShow = false//Objectlet obj:Object = { name:'張三', age:18}//array //空數(shù)組let arr:[] = []// 下面的賦值不對//arr = [1,2,3]//定義普通數(shù)組let arr1:Array<String> = ['香蕉','蘋果']let arr2:Array<Number> = [1,2,3,4]//指向聲明 不賦值let info:String info= "1111"//undefined 類型let b:undefined//元祖類型 聲明N個類型,你要根據(jù)你聲明的類型進行賦值,一一對應let arr3:[Number,String,Boolean] = [1,'字符串',true]//枚舉(有序舉例) 默認是從0開始 依次排序。如果想去修改默認值直接賦值即可enum Sex{ man, woman}//傳輸方式enum methodInfo{ get='GET',post='Post'}console.log(methodInfo.get,'枚舉');console.log(methodInfo.post,'枚舉');let type:methodInfo = methodInfo.getconsole.log(type,'type');//大部分的data屬性的結(jié)果都是來自于接口返回的數(shù)據(jù) //任意類型//anylet anyInfo:any anyInfo = 100anyInfo ='結(jié)果'console.log(anyInfo,'anyInfo')
登錄后復制
六、函數(shù)類型
無返回值
function fn(): void { console.log('無返回值');}console.log(fn(), '執(zhí)行函數(shù)');
登錄后復制
有返回值類型
function fn1(): String { return '函數(shù)有返回值'}console.log(fn1());
登錄后復制
任意類型
function fn2(): any { return '任意'}console.log(fn2());
登錄后復制
定義參數(shù)類型
//參數(shù) 一定要設(shè)定數(shù)據(jù)類型function fn3(msg: String): void { console.log(msg, '參數(shù)一')}fn3('100')
登錄后復制
默認參數(shù)
//默認參數(shù)//如果不傳遞參數(shù),就是走默認,否則就賦值你傳遞的內(nèi)容function fn4(params1: String, params2: String = '白居易'): String { return params2}console.log(fn4('李白'));console.log(fn4('曹操', '大關(guān)羽'));
登錄后復制
可選參數(shù)
//可選參數(shù) (傳不傳參數(shù)都可以)function fn5(params1: String, params2?: String): String { return params1}console.log(fn5('李白'));console.log(fn5('曹操', '大關(guān)羽'));
登錄后復制
七、類(class)
7.1基本類
//創(chuàng)建一個基本類class Zoo{ //類的作用域 省略了所有的聲明方式 //設(shè)定一個變量,未賦值會報錯,我們可以給其一個undefined類型還可以去構(gòu)造函數(shù)中賦值 public name:String | undefined constructor(newName:String){ this.name = newName console.log(this.name,'父類中的name值'); } eat(food:String):String{ return `${this.name}喜歡吃${food}` }}let zoo = new Zoo('狼')zoo.eat('肉')console.log(zoo.name,'zooname');
登錄后復制
7.2 派生類(子類) 類的繼承
//類的繼承(派生類)//繼承了父類,就擁有了父類的所有屬性和方法// 如果子類中定義的屬性和方法與父類一致,其實就是修改(重置)//子類中constructor(){ super()} 必須調(diào)用super() 它可以調(diào)用父類中的屬性和方法class Tiger extends Zoo{ name:String constructor(a:String){ //super調(diào)用父類中的屬性和方法 super(a) console.log(a,'aaaa'); this.name = a console.log(this.name,'this.name'); } eat(foods:String):String{ return '這個是一個字符串' }}let tiger = new Tiger('老虎')tiger.eat('生肉')
登錄后復制
7.3 類的修飾符
public 公有的(一般定義一個屬性,如果沒有給修飾符,它就是公有的,public是默認),它可以在類中,子類中,類外部被調(diào)用 protected 受保護的 它可以在父類與子類中被使用,不能在類的外部被調(diào)用 private 私有的 它只能在父類中被調(diào)用。不能在子類以及類的外部被調(diào)用 在類的作用域中你可以創(chuàng)建屬性,我們可以給它添加修飾符。決定了這個屬性能否被子類或者類的外部所有使用(調(diào)用)
登錄后復制
- public
///創(chuàng)建一個基本類class Zoo{ //類的作用域 省略了所有的聲明方式 //設(shè)定一個變量,未賦值會報錯,我們可以給其一個undefined類型還可以去構(gòu)造函數(shù)中賦值 // 公有的public (如果不添加這個修飾符,這個屬性默認就是公有的) public name:String | undefined constructor(newName:String){ this.name = newName console.log(this.name,'父類中的name值'); } eat(food:String):String{ return `${this.name}喜歡吃${food}` }}let zoo = new Zoo('狼')zoo.eat('肉')console.log(zoo.name,'zooname');// console.log(zoo,'zoo類實例化的結(jié)果');// console.log(zoo.eat('肉'),'執(zhí)行結(jié)果');//類的繼承(派生類)//繼承了父類,就擁有了父類的所有屬性和方法// 如果子類中定義的屬性和方法與父類一致,其實就是修改(重置)//子類中constructor(){ super()} 必須調(diào)用super() 它可以調(diào)用父類中的屬性和方法class Tiger extends Zoo{ name:String constructor(a:String){ //super調(diào)用父類中的屬性和方法 super(a) console.log(a,'aaaa'); this.name = a console.log(this.name,'this.name'); } eat(foods:String):String{ return '這個是一個字符串' }}let tiger = new Tiger('老虎')tiger.eat('生肉')console.log(tiger.name,'name 屬性 也可以用?。?!');
登錄后復制
- protected
//創(chuàng)建一個基本類class Zoo{ //類的作用域 省略了所有的聲明方式 //設(shè)定一個變量,未賦值會報錯,我們可以給其一個undefined類型還可以去構(gòu)造函數(shù)中賦值 //protected 只能在父類 和子類中被調(diào)用, 不能在類的外層被調(diào)用 protected name:String | undefined constructor(newName:String){ this.name = newName console.log(this.name,'父類中的name值'); } eat(food:String):String{ return `${this.name}喜歡吃${food}` }}let zoo = new Zoo('狼')zoo.eat('肉')console.log(zoo.name,'zooname');// console.log(zoo,'zoo類實例化的結(jié)果');// console.log(zoo.eat('肉'),'執(zhí)行結(jié)果');//類的繼承(派生類)//繼承了父類,就擁有了父類的所有屬性和方法// 如果子類中定義的屬性和方法與父類一致,其實就是修改(重置)//子類中constructor(){ super()} 必須調(diào)用super() 它可以調(diào)用父類中的屬性和方法class Tiger extends Zoo{ name:String constructor(a:String){ //super調(diào)用父類中的屬性和方法 super(a) console.log(a,'aaaa'); this.name = a console.log(this.name,'this.name'); } eat(foods:String):String{ return '這個是一個字符串' }}let tiger = new Tiger('老虎')tiger.eat('生肉')console.log(tiger.name,'name 屬性 也可以用?。?!');
登錄后復制
- private
//創(chuàng)建一個基本類class Zoo{ //類的作用域 省略了所有的聲明方式 //設(shè)定一個變量,未賦值會報錯,我們可以給其一個undefined類型還可以去構(gòu)造函數(shù)中賦值 //private 私有屬性 只能在自己的類中被調(diào)用,不能被子類以及類的外層調(diào)用 private name:String | undefined constructor(newName:String){ this.name = newName console.log(this.name,'父類中的name值'); } eat(food:String):String{ return `${this.name}喜歡吃${food}` }}let zoo = new Zoo('狼')zoo.eat('肉')console.log(zoo.name,'zooname');// console.log(zoo,'zoo類實例化的結(jié)果');// console.log(zoo.eat('肉'),'執(zhí)行結(jié)果');//類的繼承(派生類)//繼承了父類,就擁有了父類的所有屬性和方法// 如果子類中定義的屬性和方法與父類一致,其實就是修改(重置)//子類中constructor(){ super()} 必須調(diào)用super() 它可以調(diào)用父類中的屬性和方法class Tiger extends Zoo{ name:String constructor(a:String){ //super調(diào)用父類中的屬性和方法 super(a) console.log(a,'aaaa'); this.name = a console.log(this.name,'this.name'); } eat(foods:String):String{ return '這個是一個字符串' }}let tiger = new Tiger('老虎')tiger.eat('生肉')console.log(tiger.name,'name 屬性 也可以用?。。?#39;);
登錄后復制
7.4 靜態(tài)類
如果在類中聲明了類的靜態(tài)屬性和靜態(tài)方法,那么你不需要實例化,直接通過點就可以獲取到當前 靜態(tài)類的屬性/方法
登錄后復制
- 靜態(tài)屬性與靜態(tài)方法
//創(chuàng)建一個基本的靜態(tài)類class staticInfo{ //設(shè)定一個靜態(tài)屬性 static stName:String ='靜態(tài)屬性111' //設(shè)定一個靜態(tài)方法 static getTime():any{ return '時間的結(jié)果' }}console.log(staticInfo,'靜態(tài)類');console.log(staticInfo.stName,'靜態(tài)屬性');console.log(staticInfo.getTime(),'執(zhí)行你的靜態(tài)方法');
登錄后復制
7.5抽象類(abstract)
你創(chuàng)建一個抽象類,只需要定義它的描述即可,不需要去具體實現(xiàn)它的行為。誰繼承這個抽象類,誰就具體描述當前行為與骨架 舉例: 抽象(車) 這輛車 要有名字 要能跑
登錄后復制
//抽象類 必須要規(guī)定 有 名字 能開(能跑)abstract class Car{ //定義抽象屬性 abstract nameCar:String //定義抽象的方法 abstract run():String}//創(chuàng)建一個類去繼承 封裝的抽象類class BMW extends Car{ //實現(xiàn)(定義)抽象類中的 成員的具體行為 nameCar:String carAge:Number constructor(){ super() this.nameCar = '大寶馬' this.carAge = 10 } //具體實現(xiàn)抽象類中方法 run():String{ return `${this.nameCar}跑起來了。。。。` } //創(chuàng)建一個停止的方法 stop():void{ console.log('爆胎了。。。。'); }}let bmw = new BMW()console.log('哈哈哈哈');console.log(bmw.run(),'寶馬類');bmw.stop()
登錄后復制
八、接口(interface)
8.1 普通接口
/* 接口 interface 如果我們有一個普通函數(shù),但是函數(shù)的參數(shù)很復雜,如何去驗證參數(shù)的數(shù)據(jù)類型??? funtion fn(msg:String,person:Object,hobby:Array<String>){ } */// let ming = {// name:'',// age:0,// hobby:'',// sex:0,// dec:''// }//設(shè)置一個 人員信息類型接口 ====基本接口enum sexInfo { man,woman}// 這個接口專門用于人員信息的屬性驗證interface Person{ name:String, age:Number, sex:sexInfo,//枚舉類型 hobby:Array<String>, desc:String}let ming:Person ={ name:'小明子', age:19, sex:sexInfo.man, hobby:['吃飯','學習','打游戲'], desc:'這個對明的一個描述'}console.log(ming,'ming的信息驗證并賦初始值');
登錄后復制
8.2類的接口
// 接口類 interface//創(chuàng)建一個普通的接口類interface Animal{ anName:String, eatFood():String}//創(chuàng)建一個普通類 implements(實現(xiàn))class Dog implements Animal{ anName:String = '小狗子' anAge:Number | undefined eatFood():String{ return `${this.anName}喜歡吃骨頭` }}let dog = new Dog()console.log(dog,'狗的實例化');
登錄后復制
九、裝飾器
裝飾器是es7 最大的一個亮點。 我們在ts中裝飾器也是比較中要的一個概念。你可以發(fā)現(xiàn)ts用了很多最新語法,它也被看作是未來所有標準的定義 裝飾器它本身就是一個普通的函數(shù),主要用于裝飾類 類的裝飾器 類的屬性的裝飾器 類的方法的裝飾器 一定要釋放開,ts配置文件中對裝飾器的限制 "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
登錄后復制
- 類的普通裝飾器
//創(chuàng)建一個普通的類的裝飾器//裝飾器就是一個普通函數(shù)function getHttp(classInfo:any):any{ console.log(classInfo,'shui'); //當前函數(shù)的參數(shù)classInfo 是當前裝飾器裝飾的類 //在當前函數(shù)中做一些邏輯或者說去修改 創(chuàng)建類的屬性和方法 classInfo.prototype.nameInfo = 'http客戶端'}//創(chuàng)建一個類,如何調(diào)用裝飾器,通過@去調(diào)用裝飾器@getHttpclass Http{}let http = new Http()console.log(http,'http類');// console.log(http.nameInfo,'調(diào)用');
登錄后復制
- 裝飾器的傳參
//如何給裝飾器傳遞參數(shù) (工廠模式裝飾器 ,函數(shù)的返回值還是一個函數(shù))function getHttp1(params:any):any{ //裝飾器傳遞參數(shù),兩個參數(shù)分別是誰 //params它是裝飾器的參數(shù) 類型不能確定 //classInfo 是類 return (classInfo:any)=>{ console.log(classInfo,'who'); console.log(params,'params'); classInfo.prototype.paramsName = params }}// @getHttp1('張飛')@getHttp1({a:1,b:2})class Http1{}let h1 = new Http1()console.log(h1,'http類');// console.log(h1.paramsName,'http類');
登錄后復制
- 屬性裝飾器
//屬性裝飾器//創(chuàng)建一個普通裝飾器function getProps(params:any):any{ return (classInfo:any,propName:any)=>{ console.log(params,'aaaaaaaa'); console.log(classInfo,'bbbbbb'); console.log(propName,'ccccccc'); classInfo[propName] = params }}class Http2{ //調(diào)用封裝好的屬性裝飾器 @getProps('蔡文姬') httpName:String | undefined}let h2 = new Http2()console.log(h2,'h2類');console.log(h2.httpName);
登錄后復制
- 方法裝飾器
//方法裝飾器function getMethods(a:any):any{ /* 方法裝飾器的四個參數(shù) a 代表的是裝飾器傳參 b 代表的是類 c 代表的是被裝飾的方法名稱 d 代表的是方法的一些內(nèi)置屬性 */ return (b:any,c:any,d:any)=>{ console.log(a,'aaaaaaaa'); console.log(b,'bbbbbb'); console.log(c,'ccccccc'); console.log(d,'ddddddd'); }}class Http3{ //調(diào)用封裝好的屬性裝飾器 @getMethods('方法') getUrl():any{ }}let h3 = new Http3()console.log(h3,'h3類');
登錄后復制
十、最新的腳手架結(jié)合TS創(chuàng)建項目
10.1 創(chuàng)建命令
vue create 項目名稱 注意點: 1、要選擇 typescript 2、要選擇類的組件創(chuàng)建方式
登錄后復制
10.2 創(chuàng)建組件
<template> <div> <h1>歡迎來到首頁</h1> <h1>{{name}}</h1> </div> </template> <script lang='ts'> import {Vue} from 'vue-property-decorator' class Home extends Vue{ //類的作用域省略了聲明方式 constructor(){ super() //當前this 指向的是子類(包含了父類的屬性和方法) console.log(this,'this'); } } // 導出這個封裝好的子類組件 export default Home </script>
登錄后復制
10.3 data數(shù)據(jù)的創(chuàng)建
name:String //類的作用域省略了聲明方式 constructor(){ super() //當前this 指向的是子類(包含了父類的屬性和方法) console.log(this,'this'); this.name = '大白起' }
登錄后復制
10.4methods
{ //定義方法 getInfo(){ console.log('方法被點擊') } }
登錄后復制
10.5計算屬性
//計算屬性 get allPrice(){ return 100 }
登錄后復制
10.6生命周期
必須要調(diào)用組件裝飾器,否則無法觸發(fā) //類的裝飾器之組件 @Component({ }) mounted() { console.log('加載完成') }
登錄后復制
10.7組件的嵌套
//引入組件 import {Vue,Component,Watch} from 'vue-property-decorator' //類的裝飾器之組件 @Component({ components:{ vHeader } }) //視圖中 <v-header ></v-header>
登錄后復制
10.8組件通信
一、父傳子
- 父組件
<v-header :name='name' :obj = 'obj' ></v-header>
登錄后復制
- 子組件
import {Prop } from 'vue-property-decorator' export default class vNav extends Vue{ @Prop() name:any @Prop() obj:any }
登錄后復制
二、子傳父
- 子組件
<div> <button @click='toFather'>給父親</button> </div> //引入組件裝飾器 引入核心Vue類 import {Emit } from 'vue-property-decorator' //Emit方法裝飾器 傳參,傳入的參數(shù),就是你的自定義事件名稱 @Emit('自定義事件名稱') toFather(){ console.log('給父親的散文詩') return '這是給父親的散文詩' }
登錄后復制
- 父組件
<v-nav @自定義事件名稱='getGift' ></v-nav> //封裝一個獲取子組件數(shù)據(jù)的方法 getGift(e:any):void{ console.log(e,'數(shù)據(jù)源'); }
登錄后復制
8.9watch監(jiān)聽(偵聽器)
//淺監(jiān)聽 @Watch('value') getValue(newVal:any){ console.log(newVal,'新值') } //監(jiān)聽對象 //深度監(jiān)聽@Watch()這個方法裝飾器,有兩個參數(shù),一,監(jiān)聽的對象屬性。二、配置對象 @Watch('obj',{ deep:true, //深度 immediate:true //立即立刻 }) getObj(newVal:any){ console.log(newVal,'新') }
登錄后復制
推薦學習:《vue視頻教程》