Vue与TypeScript的完美结合

前言:

    TypeScript 是 JS类型的超集,并支持了泛型、类型、命名空间、枚举等特性,弥补了 JS 在大型应用开发中的不足。在我们自己单独学习 TS时,时常感觉很多知识点还是比较好理解的,但要和框架结合的话,感觉就有点糟,因为我使用Vue比较多,这里就介绍Vue 框架与 TS的结合。
    下面就结合我的经验,简单介绍一下如何在Vue中平滑的从JS过渡到TS,在各位大佬面前班门弄斧了。(想了解的更具体的话,可以参考官方文档,官方文档就是最好的入门手册)

构建:

通过官方脚手架Vue-CLI构建,tips:如果没有安装就先下载安装

npm install --global @vue/cli

最新的Vue-CLI工具允许开发者使用TS集成环境创建新项目。只需运行vue create myapp,然后,命令行会要求选择预设,使用箭头键选择 Manually select features。
在这里插入图片描述
接下来,只需确保选择了 TypeScript 和 Babel 选项即可,自2020年9月更新Vue3.0之后,目前还提供Vue项目版本的选择
在这里插入图片描述
最后配置其余设置,之后就会显示安装依赖并设置项目,只需坐等
在这里插入图片描述

目录结构:

安装完成打开项目,集成 TS 后的Vue项目目录结构大致如下所示:

|--TS - Vue|-- .browserslistrc     # browserslistrc 配置文件 (用于支持 Autoprefixer)|-- .eslintrc.js        # eslint 配置|-- .gitignore|-- babel.config.js     # babel-loader 配置|-- package-lock.json|-- package.json        # package.json 依赖|-- postcss.config.js   # postcss 配置|-- README.md|-- tsconfig.json       # TS 配置文件(主要用于指定待编译的文件和定义编译选项)|-- vue.config.js       # vue-cli 配置|-- public              # 静态资源 |   |-- favicon.ico     # favicon图标|   |-- index.html      # html模板|-- src|   |-- App.vue         # 入口页面|   |-- main.ts         # 入口文件 加载组件 初始化等|   |-- shims-tsx.d.ts	#ts配置文件(允许.tsx 结尾的文件,在 Vue 项目中编写 jsx 代码)|   |-- shims-vue.d.ts	#ts配置文件(主要用于TS识别.vue 文件,TS默认并不支持导入 vue 文件)|   |-- assets          # 主题 字体等静态资源 (由 webpack 处理加载)|   |-- components      # 全局组件|   |-- router          # 路由|   |-- store           # 全局 vuex store|   |-- views           # 所有页面|-- tests               # 测试
使用:

先了解一下vue 中使用 TS 非常好用的几个库文件:

  • vue-class-component
import Component from 'vue-class-component'
  • vue-property-decorator
import { Vue, Component, Inject, Provide, Prop, Model, Watch, Emit, Mixins } from 'vue-property-decorator'
  • vuex-module-decorators
import { Module, VuexModule, Mutation, Action, MutationAction, getModule } from 'vuex-module-decorators'
  • vuex-class
import { State, Getter, Action, Mutation, namespace } from 'vuex-class'
Component声明:
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';@Component
export default class Test extends Vue {}
Data对象:
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';@Component
export default class Test extends Vue {private name: string;
}
Prop声明:
@Prop({ default: false }) private first!: boolean;
@Prop({ default: true }) private second!: string;
@Prop({ default: "" }) private num!: number;

tips:

  • !: 表示一定存在,?: 表示可能不存在(叫做赋值断言)
  • @Prop(options: (PropOptions | Constructor[] | Constructor) = {})
    • PropOptions,可以使用以下选项:type,default,required,validator
    • Constructor[],指定 prop 的可选类型
    • Constructor,例如 String,Number,Boolean 等,指定 prop 的类型
Method声明:
public getSome(): void {//函数主体
}
Watch 监听属性:
@Watch("totalPrice", { immediate: true,deep: true })
private onTotalPriceChange(newVal:number, oldVal:number) {//监听执行函数主体
}

tips:

  • @Watch(path: string, options: WatchOptions = {})
  • options 包含两个属性:
    • immediate?:boolean 侦听开始之后是否立即调用(即:首次是否执行)
    • deep?:boolean 被侦听的变量为对象时,需要使用才能监听它的属性改变
Computed 计算属性:
public get allPrice() {// 计算逻辑主体return + “最后结果”
}
生命周期函数:
public created(): void {console.log('created');
}public mounted():void{console.log('mounted')
}
Emit 事件:
import { Vue, Component, Emit } from 'vue-property-decorator'
@Component
export default class newComponent extends Vue {count = 0@Emit()addToCount(n: number) {this.count += n}@Emit('reset')resetCount() {this.count = 0}@Emit()returnValue() {return 10}@Emit()onInputChange(e) {return e.target.value}@Emit()promise() {return new Promise(resolve => {setTimeout(() => {resolve(20)}, 0)})}
}

tips:

  • @Emit(event?: string)
  • @Emit 装饰器接收一个可选参数,该参数是Emit的第一个参数充当事件名,如果没有提供这个参数,那么会将回调函数名,例如 priceChange 转为 price-change,并将其作为事件名
  • @Emit 会将回调函数的返回值作为第二个参数,如果返回值是一个 Promise 对象,$emit 会在 Promise 对象被标记为 resolved 之后触发
  • @Emit 的回调函数的参数,会放在其返回值之后,一起被$emit 当做参数使用
Vuex状态管理:
import Vue from 'vue'
import Component from 'vue-class-component'
import { State, Getter, Action, Mutation, namespace } from 'vuex-class'const someModule = namespace('path/to/module')@Component
export class MyComp extends Vue {@State('foo') stateFoo@State(state => state.bar) stateBar@Getter('foo') getterFoo@Action('foo') actionFoo@Mutation('foo') mutationFoo@someModule.Getter('foo') moduleGetterFoo// 如果省略参数,请使用属性名称, 对于每个状态/getter/action/mutation类型@State foo@Getter bar@Action baz@Mutation quxcreated () {this.stateFoo	 // -> store.state.foothis.stateBar	 // -> store.state.barthis.getterFoo	 // -> store.getters.foothis.actionFoo({ value: true })	 // -> store.dispatch('foo', { value: true })this.mutationFoo({ value: true }) 	// -> store.commit('foo', { value: true })this.moduleGetterFoo	 // -> store.getters['path/to/module/foo']}
}

    
    今天的分享到此结束,希望对您有所帮助,如果文章有错误或者有什么相关的建议,请直接私信联系我,谢谢!!!此外你如果感觉喜欢请点击进行关注,你的观看是我最大的动力,以后会不定时的分享学习心得,敬请期待(* ̄︶ ̄)(* ̄︶ ̄)(* ̄︶ ̄)

——来自一个程序猿小白的自我成长 && 学习分享


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部