typescript在vue中使用,vue3 typescript实战
TypeScript是微软开发的免费开源编程语言。它是JavaScript的超集,扩展了JavaScript的语法。本文主要介绍Vue新伙伴TypeScript的快速入门练习,有需要的朋友可以参考一下。
:
目录
1.使用官方脚手架建造2。分析项目目录3。从3开始。TypeScript 3.1基本类型和扩展类型3.2泛型:Generics3.3自定义类型:InterfacevsType alias3.4实现和继承:实现vs扩展3.5声明文件和命名空间:声明和命名空间3.6访问修饰符:private、public、protected3.7可选参数(?)和非空断言运算符(!) 4.Vue组件的Ts编写4.1vue-class-component4.2添加全局工具4.3 Axios使用和封装vue官方从版本2.6.X开始用Ts进行了部分重写
我个人对更严格的流派限制没有正面看法。毕竟习惯了各种类型转换的骚写。
在最近的一个项目中,它是TypeScript Vue,毛吉拉,学习它...................
注意本文标题的“前面”。本文的目的是讲Ts混合框架的使用,而不是类API。
1. 使用官方脚手架构建
npm安装-g @vue/cli
#或者
yarn全局添加@vue/cli
新的Vue CLI工具允许开发人员使用TypeScript集成环境创建新项目。
只要运行vue创建我的应用程序。
然后,命令行会要求您选择一个预设。使用箭头键选择手动选择特征。
接下来,只需确保选择了TypeScript和Babel选项,如下所示:
这个操作之后,它会问你是否要使用类风格的组件语法。
然后配置其余的设置,如下图所示。
vucli工具现在将安装所有依赖项并设置项目。
接下来,运行项目。
2. 项目目录解析
通过tree命令检查目录结构后,可以发现其结构与正常的有很大不同。
这里主要关注两个文件:shims-tsx.d.ts和Shims-Vue。D.TS
两句话总结:
Shims-tsx.d.ts,它允许您在Vue项目中编写jsx代码,文件以。tsx。
Shims-vue.d.ts主要用于打字稿识别。vue文件。默认情况下,Ts不支持导入vue文件。这个文件告诉ts所有导入的。vue文件应被视为VueConstructorVue。
这时,当我们打开友好的src/components/HelloWorld.vue时,会发现写法大相径庭。
模板
你好
h1{{ msg }}/h1
!-省略-
/div
/模板
脚本语言
从“vue-property-decorator”导入{ Component,Prop,Vue };
@组件
导出默认类HelloWorld扩展Vue {
@Prop()私信!字符串;
}
/脚本
!-添加“scoped”属性以将CSS仅限制到此组件-
样式范围/样式
至此,我们准备开启新的一章,TypeScript快速入门和vue-property-decorator。
3.TypeScript极速入门
3.1 基本类型和扩展类型
脚本和Javascript共享相同的基本类型,但是还有一些附加类型。
元组
列举型别
没有任何空隙
1.基本类型的集合
//支持数字、二进制、八进制和十六进制。
设dec literal:number=6;
设hex literal:number=0x f00d;
//字符串,单引号或者双引号都可以。
let name:string= bob ;
let句子:string=`你好,我叫${ name }。
//数组,第二种方法是使用数组泛型,数组元素类型:
let list: number[]=[1,2,3];
字母列表:Arraynumber=[1,2,3];
设u: undefined=未定义;
设n:null=null;
2.特殊类型
1.元组Tuple
将元组想象成有组织的数组。您需要以正确的顺序预定义数据类型。
const messyArray=[ something ,2,true,undefined,null];
const tuple:[数字,字符串,字符串]=[24, Indrek , Lasn]
如果不遵循对元组进行预排序的索引规则,Typescript将向您发出警告。
(元组的第一项应为数字类型)
2.枚举枚举
枚举类型是JavaScript标准数据类型的补充。与其他语言(如C#)一样,枚举类型可以为一组值提供友好的名称。
//默认情况下,元素从0开始编号,也可以手动从1开始编号。
枚举颜色{红色=1,绿色=2,蓝色=4}
设c: Color=颜色。绿色;
let Color name:string=Color[2];
console . log(color name);//输出“Green ”,因为在上面的代码中它的值是2
另一个很好的例子是使用枚举来存储应用程序状态。
3.空的
在打字稿中,你必须在函数中定义返回类型。像这样:
如果没有返回值,将会报告一个错误:
我们可以将其返回值定义为void:
你现在不能回来。
4.任何的
呃.不管是什么类型,当你不能确定你面对的是什么类型的时候,你可以用这个。
但是,应该小心使用。用多了就失去了使用Ts的意义。
让人:何=前端劝阻老师
人=25
person=true
主要应用场景有:
访问第三方库
Ts用在前期。
5.从不
用很浅显的话来形容就是:‘永远不是你永远得不到的父亲。’
具体行为是:
抛出新错误(消息)
返回错误(“出现故障”)
While (true) {} //有一个无法到达的端点。
3.类型断言
的简短定义是:它可用于手动指定值的类型。
有两种写法,尖括号和as:
let someValue: any=这是一个字符串;
设strLength:number=(string some value)。长度;
设strLength:number=(some value as string)。长度;
使用示例如下:
当TypeScript不确定某个关节类型的变量是哪种类型时,我们只能访问该关节类型的所有类型共有的属性或方法:
函数getLength(something:string number):number {
返回某物. length;
}
//index.ts(2,22):错误TS2339:类型“string number”上不存在属性“length”。
//属性“length”在类型“number”上不存在。
如果访问长度,就会报错,有时候,在不确定类型的时候,我们真的需要访问其中一个类型的属性或者方法。这时,我们需要断言以免报告错误:
函数getLength(something:string number):number {
if ((stringsomething)。长度){
return (stringsomething)。长度;
}否则{
返回something.toString()。长度;
}
}
3.2 泛型:Generics
软件工程的一个主要部分是构建组件,组件不仅需要有明确的定义和统一的接口,还需要可重用。支持现有数据类型和将来要添加的数据类型的组件为大型软件系统的开发过程提供了极大的灵活性。
在C#和Java中,‘泛型’可以用来创建可重用的组件,组件可以支持多种数据类型。这允许用户根据自己的数据类型使用组件。
1.通用方法
在TypeScript中,声明泛型方法有以下两种方式:
函数gen_func1T(arg: T): T {
返回参数;
}
//或者
设gen _ func 2:T(arg:T)=T=function(arg){
返回参数;
}
调用方式也有两种:
gen _ func 1 string( Hello world );
gen _ func 2( Hello world );
//第二个调用方法可以省略类型参数,因为编译器会根据传入的参数自动识别对应的类型。
2.仿制药和任何
任何,一种特殊类型的Ts,在具体使用中可以代替任何类型。乍一看,这两者似乎没有什么区别,其实不然:
//方法1:带任意参数的方法
函数any_func(arg: any): any {
console . log(arg . length);
返回参数;
}
//方法2:数组泛型方法
函数array _ funcT(arg:array t):array t {
console . log(arg . length);
返回参数;
}
首先,输出arg参数的length属性。因为any可以替换任何类型,所以当传入的参数不是数组或具有length属性的对象时,此方法会引发异常。
第二,方法定义了参数类型为Array的泛型,肯定会有length属性,所以不会抛出异常。
3.通用类型
通用接口:
接口泛型_ interfaceT {
(arg:T):T;
}
func_demoT函数(arg: T): T {
返回参数;
}
let func 1:Generics _ interface number=func _ demo;
func 1(123);//正确类型的实际参数
func 1( 123 );//错误类型的实际参数
3.3 自定义类型:InterfacevsType alias
界面,在中国翻译成Interface。
键入别名,键入别名。
1.类似
都可以用来描述一个对象或函数:
界面用户{
名称:字符串
年龄:数量
}
键入User={
名称:字符串
年龄:数量
};
接口设置用户{
(姓名:字符串,年龄:数字):void
}
type SetUser=(name: string,age:number):void;
都允许拓展(extends):
而接口类型是可以扩展的,它们并不是相互独立的,也就是说,接口可以是扩展类型,而类型也可以是扩展接口。虽然效果差不多,但是两者语法不同。
interface extends interface
接口名称{
名称:字符串;
}
界面用户扩展名称{
年龄:号;
}
type extends type
类型名称={
名称:字符串;
}
键入User=Name { age:number };
interface extends type
类型名称={
名称:字符串;
}
界面用户扩展名称{
年龄:号;
}
type extends interface
接口名称{
名称:字符串;
}
键入User=Name {
年龄:号;
}
2.差异
type可以而interface不行
类型可以声明基本类型别名、联合类型、元组和其他类型。
//基本类型别名
类型名称=字符串
//联合类型
界面狗{
wong();
}
接口类别{
苗();
}
宠物=狗猫
//明确定义数组每个位置的类型
类型宠物清单=[狗,宠物]
Type语句也可以用来获取实例的类型进行赋值。
//当您想要获取变量的类型时,请使用typeof
let div=document . createelement( div );
类型B=div的类型
其他骚操作
type string or number=string number;
type Text=string { Text:string };
type name lookup=dictionary string,Person。
type CallbackT=(data:T)=void;
type PairT=[T,T];
类型坐标=Pairnumber
type TreeT=T { left: TreeT,right:TreeT };
interface可以而type不行
接口可以声明merge。
界面用户{
名称:字符串
年龄:数量
}
界面用户{
性别:字符串
}
/*
用户界面是{
名称:字符串
年龄:数量
性别:字符串
}
*/
接口有可选属性和只读属性。
可选属性
并非接口中的所有属性都是必需的。有些只在一定条件下存在或者根本不存在。例如,只有传递给函数的参数对象中的一些属性被赋值。具有可选属性的接口类似于公共接口定义,除了在可选属性的名称定义之后添加一个?符号。如下
接口人{
名称:字符串;
年龄?数字;
性别?数字;
}
只读属性
顾名思义,这个属性是不可写的,对象属性的值只能在对象刚创建的时候修改。您可以在属性名称前使用readonly来指定只读属性,如下所示:
界面用户{
readonly log in name:string;
密码:字符串;
}
上面的示例表明,在用户对象初始化完成后,不能修改loginName。
3.4 实现与继承:implements vs extends
扩展显然是ES6中的类继承,那么实现是做什么的呢?它和扩展有什么不同?
实施,实施。与C#或Java中的interface基本函数一样,TypeScript也可以用它来显式地强制一个类符合某种约定。
implement基本用法:
界面开发人员{
名称:字符串;
年龄?数字;
}
//好的
类dev实现IDeveloper {
name= Alex
年龄=20;
}
//好的
类dev2实现IDeveloper {
name= Alex
}
//错误
类dev3实现IDeveloper {
name= Alex
年龄= 9 ;
}
extends是继承的父类,这两者实际上可以混合使用:
类A扩展了B实现了C、D、E
接口的用法和类型有:
3.5 声明文件与命名空间:declare和namespace
我们前面讲过vue项目中的shims-tsx.d.ts和shims-vue.d.ts,它们的初始内容如下:
//shims-tsx.d.ts
从“vue”导入Vue,{ VNode };
声明全局{
命名空间JSX {
//tslint:禁用非空接口
接口元素扩展了VNode {}
//tslint:禁用非空接口
接口元素类扩展Vue {}
接口内部元素{
[elem:string]:any;
}
}
}
//shims-vue.d.ts
声明模块“*”。vue {
从“Vue”导入Vue;
导出默认Vue
}
声明:在使用第三方库时,我们需要参考其声明文件,才能得到代码补全、界面提示等相应的功能。
下面是几个常用的:
Declare var声明全局变量。
Declare函数声明一个全局方法
声明类声明一个全局类
Declare enum声明全局枚举类型。
声明全局扩展全局变量。
声明模块扩展模块
名称空间:“内部模块”现在称为“名称空间”
模块X {相当于当前推荐的编写命名空间X {)
与其他JS库协作
与模块类似,您也可以创建。d.ts文件,您可以创建这样一个声明文件:
声明命名空间D3{
导出接口选择器{.}
}
声明变量d3: D3。基地;
所以上面的两个文件:
Shims-tsx.d.ts,在全局变量global中批量命名几个内部模块。
Shims-vue.d.ts,这意味着告诉TypeScript*的文件。vue后缀可以交给Vue模块处理。
3.6 访问修饰符:private、public、protected
其实很容易理解:
默认为公共
当成员被标记为私有时,不能在声明它的类之外访问它,例如:
动物类{
私有名:string
构造函数(名称:字符串){
this.name=theName
}
}
让a=新动物(猫)。姓名;//错误, name 是私有的
Protected类似于private,但是,可以在派生类中访问protected成员。
动物类{
受保护的名称:string
构造函数(名称:字符串){
this.name=theName
}
}
犀牛类延伸动物{
构造函数(){
超级(‘犀牛’);
}
getName() {
Console.log(this.name) //这里的名字是Animal类中的名字。
}
}
3.7 可选参数 ( ?: )和非空断言操作符(!.)
可选参数
函数buildName(firstName: string,lastName?字符串){
返回名字 姓氏
}
//错误演示
buildName(名字,姓氏,姓氏)
//正确演示
buildName(“名字”)
//正确演示
buildName(名字,姓氏)
非空断言操作符:
当确定变量值不能为空时,可以使用。
与可选参数不同,非空断言操作符不防止空或未定义。
让s=e!姓名;//断言E非空并访问name属性
发展
1.用于属性还是参数?指示属性或参数是可选的。
2.用于属性或参数中!表示强制解析(告诉typescript编译器这里必须有值),常用于vue-decorator中的@Prop。
3.使用after变量!指示类型推理不包括null和undefined。
4.Vue组件的Ts写法
vue2.5以后,vue对ts的支持更好了。根据官方文件,vue是和typescript结合在一起的,可以有两种写法:
Vue.extend
从“vue”导入Vue
常量组件=Vue.extend({
//类型推理已启用
})
vue-class-component
从“vue-property-decorator”导入{ Component,Vue,Prop }
@组件
导出默认类测试扩展Vue {
@Prop({ type: Object })
私有测试:{ value: string }
理想情况下,Vue.extend的写作风格是学习成本最低的。在现有写入方式的基础上,迁移成本几乎为零。
但是,Vue.extend模式需要配合mixins使用。typescript无法识别mixin中定义的方法。
,表示会出现丢失代码提示、类型检查、编译报错等问题。。
菜鸟做选择,老板选最好的。直接说第二个吧:
4.1vue-class-component
让我们回到src/components/HelloWorld.vue
模板
你好
h1{{ msg }}/h1
!-省略-
/div
/模板
脚本语言
从“vue-property-decorator”导入{ Component,Prop,Vue };
@组件
导出默认类HelloWorld扩展Vue {
@Prop()私信!字符串;
}
/脚本
!-添加“scoped”属性以将CSS仅限制到此组件-
样式范围/样式
写过python的学生应该会觉得似曾相识:
Vue-property-decorator,一个官方支持的库,提供了函数* * decorator (modifier) * *语法。
1.功能修饰符@
“@”与其说是修饰函数,不如说是引用和调用它的函数。
或者用白话描述:@:‘下面都是我围着的。’
举个栗子的例子。下面的代码包含两个函数。如果没有调用它们,将会有输出结果:
测试(f){
console.log(before . );
f()
console.log(after . );
}
@测试
func(){
console.log(func被调用);
}
直接运行并输出结果:
以前.
调用了func
在.之后.
可以看到上面的代码:
只定义了两个函数:测试和func,没有调用它们。
如果没有@测试,运行应该是没有任何输出的。
但是,解释器读到函数修饰符"@"的时候,后面步骤会是这样:
去调用试验函数,测试函数的入口参数就是那个叫" func "的函数;
试验函数被执行,入口参数的(也就是功能函数)会被调用(执行);
换言之,修饰符带的那个函数的入口参数,就是下面的那个整个的函数。有点儿类似Java脚本语言里面的函数a (function () {.});
2 .vue-属性-装饰和状态管理级提供的装饰器
vue-属性-装饰的装饰器:
@道具
@PropSync
@提供
@型号
@手表
@注入
@提供
@Emit
@组件(由vue类组件提供)
混合蛋白(由vue类组件提供的名为混入类的辅助函数)
状态管理级的装饰器:
@州
@Getter
@行动
@突变
我们拿原始某视频剪辑软件组件模版来看:
从" @/组件"导入{componentA,componentB };
导出默认值{
组件:{ componentA,componentB},
道具:{
propA: { type: Number },
propB: {默认值:默认值 },
propC: { type: [String,Boolean] },
}
//组件数据
data () {
返回{
消息:"你好"
}
},
//计算属性
计算值:{
reversedMessage () {
返回this.message.split( ).反转()。联接("")
}
//Vuex数据
步骤(){
归还这个store.state.count
}
},
方法:{
changeMessage () {
this.message=再见
},
getName() {
让name=this .$store.getters[person/name]
返回名称
}
},
//生命周期
已创建(){ },
已安装(){ },
已更新(){ },
已销毁(){ }
}
以上模版替换成修饰符写法则是:
从" vue-属性-装饰"导入{ Component,Vue,Prop };
从“vuex级”导入{ State,Getter };
从" @/人"导入{ count,name }
从" @/组件"导入{ componentA,componentB };
@组件({
组件:{ componentA,componentB},
})
导出默认类编译扩展Vue{
@Prop(Number) readonly propA!数字未定义
@Prop({ default:默认值})只读propB!字符串
@Prop([String,Boolean]) readonly propC!字符串布尔值未定义
//原数据
消息=你好
//计算属性
private get reversed消息():string[]{
返回this.message.split( ).反转()。联接("")
}
//Vuex数据
@ State((State:IRootState)=State .预订currentStep)步!数字
@Getter( person/name) name!名称
//方法
public changeMessage (): void {
this.message=再见
},
public getName(): string {
设storeName=name
返回商店名称
}
//生命周期
私有创建():void { },
私有挂载():void { },
私有更新():void { },
私有销毁():void { }
}
正如你所看到的,我们在生命周期列表那都添加二等兵电影站方法,因为这不应该公开给其他组件。
而不对方法做私有约束的原因是,可能会用到@Emit来向父组件传递信息。
4.2 添加全局工具
引入全局模块,需要改主页面:
从“Vue”导入Vue
从导入应用程序. 1/app。vue ;
从导入路由器./路由器;
从导入存储./store ;
vue。配置。生产提示=假;
新Vue({
路由器,
店,
render: (h)=h(App),
}).$ mount( # app );
npm i VueI18n
从“Vue”导入Vue
从导入应用程序. 1/app。vue ;
从导入路由器./路由器;
从导入存储./store ;
//新模块
从导入i18n ./i18n’;
vue。配置。生产提示=假;
新Vue({
路由器,
店,
i18n,//新模块
render: (h)=h(App),
}).$ mount( # app );
但仅仅这样,还不够。你需要动src/vue-shim.d.ts:
//声明全局方法
声明模块" vue/类型/vue"{
界面Vue {
readonly $ i18n:vuei 18 next;
$ t:翻译功能;
}
}
之后使用这个i18n()的话就不会报错了。
4.3 Axios 使用与封装
爱可信的封装千人千面
如果只是想简单在分时(同分时)里体验使用Axios,可以安装vue-axios简单使用Axios
$ npm i axios vue-axios
主页面添加:
从“vue”导入某视频剪辑软件
从" axios "导入爱可信
从“vue-axios”导入VueAxios
Vue.use(VueAxios,Axios)
然后在组件内使用:
Vue.axios.get(api).然后((响应)={
console.log(response.data)
})
this.axios.get(api).然后((响应)={
console.log(response.data)
})
这个http.get(api).然后((响应)={
console.log(response.data)
})
1.新建文件请求。分时(同timesharing)
文件目录:
-api
- main.ts //实际调用
-utils
- request.ts //接口封装
2 .请求文件解析
从" axios "导入*作为axios
从" @/商店"导入商店;
//这里可根据具体使用的用户界面组件库进行替换
从"万特"导入{ Toast };
从" axios "导入{ AxiosResponse,AxiosRequestConfig }。
/* baseURL按实际项目来定义*/
const base URL=进程。环境。vue _ APP _ URL
/* 创建爱可信实例*/
const service=axios。默认。创建({
baseURL,
超时:0,//请求超时时间
maxContentLength: 4000,
});
服务。截击机。请求。使用((config:AxiosRequestConfig)={
返回配置;
},(错误:任何)={
承诺.拒绝(错误);
});
服务。拦截器。响应。使用(
(响应:AxiosResponse)={
if (response.status!==200) {
Toast.fail(请求错误!);
}否则{
返回响应.数据
}
},
(错误:任何)={
返回承诺。拒绝(错误);
});
导出默认服务;
为了方便,我们还需要定义一套固定的爱可信返回的格式,新建ajax.ts:
导出接口AjaxResponse {
代码:数字;
数据:任意;
消息:字符串;
}
3 .主服务接口调用:
//api/main.ts
导入请求自./utils/request ;
//获取
导出函数getSomeThings(params:any) {
退货请求({
URL:"/API/get something s ",
});
}
//发布
导出函数后缀(params:any) {
退货请求({
URL:"/API/后置内容",
方法:"发布",
数据:参数
});
}
5.编写一个组件
为了减少时间,我们来替换掉src/components/HelloWorld.vue,做一个博客帖子组件:
模板
div class=blogpost
h2{{ post.title }}/h2
p{{ post.body }}/p
p class=meta 由{{ post.author }}于{{ date }}/p
/div
/模板
脚本语言
从" vue-属性-装饰"导入{ Component,Prop,Vue };
//在这里对数据进行类型约束
导出界面发布{
标题:字符串;
正文:字符串;
作者:弦;
发布日期:日期;
}
@组件
导出默认类编译扩展Vue {
@Prop()私帖!岗位;
获取日期(){
返回` ${ this。贴吧。发布日期。getdate()}/${ this。贴吧。发布日期。getmonth()}/${ this。贴吧。发布日期。get full year()} `;
}
}
/脚本
样式范围
h2 {
文本装饰:下划线;
}
p.meta {
字体样式:斜体;
}
/风格
然后在Home.vue中使用:
模板
div class=home
img alt=Vue logo src=./assets/logo.png
你好,世界博客中的“blogPost”:post=“blogPost”:key=“blogPost”。标题/
/div
/模板
脚本语言
从" vue-属性-装饰"导入{ Component,Vue };
从" @/components/HelloWorld.vue "导入HelloWorld,{ Post };//@是/src的别名
@组件({
组件:{
HelloWorld,
},
})
导出默认类家庭扩展Vue {
private blogPosts: Post[]=[
{
标题:"我的第一篇博客!",
正文:“Lorem ipsum dolor sit amet。”,
作者:"埃尔克",
发布日期:新日期(2019,1,18),
},
{
标题:"看,我正在写博客!",
正文:"为我欢呼,这是我的第二篇帖子!",
作者:"埃尔克",
发布日期:新日期(2019,1,19),
},
{
标题:又一个?,
正文:"又一个!",
作者:"埃尔克",
发布日期:新
Date(2019, 1, 20),
},
];
}
</script>
这时候运行项目:
这就是简单的父子组件
而关于Class API撤销,其实还是挺舒服的。 用class 来编写 Vue组件确实太奇怪了。 (所以本篇Ts入门压根没写Class API)
以上就是Vue新搭档TypeScript快速入门实践的详细内容,更多关于Vue TypeScript快速入门的资料请关注我们其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。