We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
近几年前端对 TypeScript的呼声越来越高,Typescript也成为了前端必备的技能。TypeScript 是 JS类型的超集,并支持了泛型、类型、命名空间、枚举等特性,弥补了 JS 在大型应用开发中的不足。
在单独学习 TypeScript时,你会感觉很多概念还是比较好理解的,但是和一些框架结合使用的话坑还是比较多的,例如使用 React、Vue 这些框架的时候与 TypeScript 的结合会成为一大障碍,需要去查看框架提供的.d.ts的声明文件中一些复杂类型的定义、组件的书写方式等都要做出不小的调整。
本篇文章主要是结合我的经验和大家聊一下如何在Vue中平滑的从js过渡到ts,阅读本文建议对 TypeScript 有一定了解,因为文中对于一些 TypeScript 的基础的知识不会有太过于详细的讲解。(具体可以参考官方文档https://www.w3cschool.cn/typescript/typescript-tutorial.html,官方文档就是最好的入门手册)
Vue
js
ts
https://www.w3cschool.cn/typescript/typescript-tutorial.html
通过官方脚手架构建安装
# 1. 如果没有安装 Vue CLI 就先安装 npm install --global @vue/cli
最新的Vue CLI工具允许开发者 使用 TypeScript 集成环境 创建新项目。
Vue CLI
只需运行vue create my-app。
vue create my-app
然后,命令行会要求选择预设。使用箭头键选择 Manually select features。
接下来,只需确保选择了 TypeScript 和 Babel 选项,如下图:
然后配置其余设置,如下图:
设置完成 vue cli 就会开始安装依赖并设置项目。
安装完成打开项目,你会发现集成 ts 后的项目目录结构是这样子的:
|-- 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 # typescript 配置 |-- vue.config.js # vue-cli 配置 |-- public # 静态资源 (会被直接复制) | |-- favicon.ico # favicon图标 | |-- index.html # html模板 |-- src | |-- App.vue # 入口页面 | |-- main.ts # 入口文件 加载组件 初始化等 | |-- shims-tsx.d.ts | |-- shims-vue.d.ts | |-- assets # 主题 字体等静态资源 (由 webpack 处理加载) | |-- components # 全局组件 | |-- router # 路由 | |-- store # 全局 vuex store | |-- styles # 全局样式 | |-- views # 所有页面 |-- tests # 测试
其实大致看下来,与之前用js构建的项目目录没有什么太大的不同,区别主要是之前 js 后缀的现在改为了ts后缀,还多了tsconfig.json、shims-tsx.d.ts、shims-vue.d.ts这几个文件,那这几个文件是干嘛的呢:
tsconfig.json
shims-tsx.d.ts
shims-vue.d.ts
开始前我们先来了解一下在 vue 中使用 typescript 非常好用的几个库
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'
创建组件的方式变成如下
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'; @Component export default class Test extends Vue { }
import { Component, Prop, Vue, Watch } from 'vue-property-decorator'; @Component export default class Test extends Vue { private name: string; }
@Prop({ default: false }) private isCollapse!: boolean; @Prop({ default: true }) private isFirstLevel!: boolean; @Prop({ default: "" }) private basePath!: string;
js 下是需要在 method 对象中声明方法,现变成如下
public clickFunc(): void { console.log(this.name) console.log(this.msg) }
@Watch("$route", { immediate: true }) private onRouteChange(route: Route) { const query = route.query as Dictionary<string>; if (query) { this.redirect = query.redirect; this.otherQuery = this.getOtherQuery(query); } }
public get allname() { return 'computed ' + this.name; }
allname 是计算后的值,name 是被监听的值
public created(): void { console.log('created'); } public mounted():void{ console.log('mounted') }
import { Vue, Component, Emit } from 'vue-property-decorator' @Component export default class MyComponent 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) }) } }
使用 js 写法
export default { data() { return { count: 0 } }, methods: { addToCount(n) { this.count += n this.$emit('add-to-count', n) }, resetCount() { this.count = 0 this.$emit('reset') }, returnValue() { this.$emit('return-value', 10) }, onInputChange(e) { this.$emit('on-input-change', e.target.value, e) }, promise() { const promise = new Promise(resolve => { setTimeout(() => { resolve(20) }, 0) }) promise.then(value => { this.$emit('promise', value) }) } } }
在使用 store 装饰器之前,先过一下传统的 store 用法吧
export default { namespaced:true, state:{ foo:"" }, getters:{ getFoo(state){ return state.foo} }, mutations:{ setFooSync(state,payload){ state.foo = payload } }, actions:{ setFoo({commit},payload){ commot("getFoo",payload) } } }
然后开始使用vuex-module-decorators
import { VuexModule, Mutation, Action, getModule, Module } from "vuex-module-decorators";
VuexModule 用于基本属性
VuexModule
export default class TestModule extends VuexModule { }
VuexModule 提供了一些基本属性,包括 namespaced,state,getters,modules,mutations,actions,context
@Module 标记当前为 module
@Module
@Module({ dynamic: true, store, name: "settings" }) class Settings extends VuexModule implements ISettingsState { }
module 本身有几种可以配置的属性:
@Mutation 标注为 mutation
@Mutation
@Mutation private SET_NAME(name: string) { // 设置用户名 this.name = name; }
@Action 标注为 action
@Action
@Action public async Login(userInfo: { username: string; password: string }) { // 登录接口,拿到token let { username, password } = userInfo; username = username.trim(); const { data } = await login({ username, password }); setToken(data.accessToken); this.SET_TOKEN(data.accessToken); }
getModule 得到一个类型安全的 store,module 必须提供 name 属性
getModule
export const UserModule = getModule(User);
我之前基于 ts+vue+element 构建了一个简单的中后台通用模板。
涵盖的功能如下:
- 登录 / 注销 - 权限验证 - 页面权限 - 权限配置 - 多环境发布 - Dev / Stage / Prod - 全局功能 - 动态换肤 - 动态侧边栏(支持多级路由嵌套) - Svg 图标 - 全屏 - 设置 - Mock 数据 / Mock 服务器 - 组件 - ECharts 图表 - 表格 - 复杂表格 - 控制台 - 引导页 - 错误页面 - 404
里面对于在 vue 中使用 typescript 的各种场景都有很好的实践,大家感兴趣的可以参考一下,https://github.com/easy-wheel/ts-vue,当然不要吝惜你的 star!!!
https://github.com/easy-wheel/ts-vue
你可以关注我的同名公众号【前端森林】,这里我会定期发一些大前端相关的前沿文章和日常开发过程中的实战总结。当然,我也是开源社区的积极贡献者,github地址https://github.com/Cosen95,欢迎star!!!
https://github.com/Cosen95
The text was updated successfully, but these errors were encountered:
No branches or pull requests
引言
近几年前端对 TypeScript的呼声越来越高,Typescript也成为了前端必备的技能。TypeScript 是 JS类型的超集,并支持了泛型、类型、命名空间、枚举等特性,弥补了 JS 在大型应用开发中的不足。
在单独学习 TypeScript时,你会感觉很多概念还是比较好理解的,但是和一些框架结合使用的话坑还是比较多的,例如使用 React、Vue 这些框架的时候与 TypeScript 的结合会成为一大障碍,需要去查看框架提供的.d.ts的声明文件中一些复杂类型的定义、组件的书写方式等都要做出不小的调整。
本篇文章主要是结合我的经验和大家聊一下如何在
Vue
中平滑的从js
过渡到ts
,阅读本文建议对 TypeScript 有一定了解,因为文中对于一些 TypeScript 的基础的知识不会有太过于详细的讲解。(具体可以参考官方文档https://www.w3cschool.cn/typescript/typescript-tutorial.html
,官方文档就是最好的入门手册)构建
通过官方脚手架构建安装
最新的
Vue CLI
工具允许开发者 使用 TypeScript 集成环境 创建新项目。只需运行
vue create my-app
。然后,命令行会要求选择预设。使用箭头键选择 Manually select features。
接下来,只需确保选择了 TypeScript 和 Babel 选项,如下图:
然后配置其余设置,如下图:
设置完成 vue cli 就会开始安装依赖并设置项目。
目录解析
安装完成打开项目,你会发现集成 ts 后的项目目录结构是这样子的:
其实大致看下来,与之前用
js
构建的项目目录没有什么太大的不同,区别主要是之前 js 后缀的现在改为了ts后缀,还多了tsconfig.json
、shims-tsx.d.ts
、shims-vue.d.ts
这几个文件,那这几个文件是干嘛的呢:tsconfig.json
: typescript配置文件,主要用于指定待编译的文件和定义编译选项shims-tsx.d.ts
: 允许.tsx 结尾的文件,在 Vue 项目中编写 jsx 代码shims-vue.d.ts
: 主要用于 TypeScript 识别.vue 文件,Ts 默认并不支持导入 vue 文件使用
开始前我们先来了解一下在 vue 中使用 typescript 非常好用的几个库
vue-class-component
:vue-class-component
是一个 Class Decorator,也就是类的装饰器vue-property-decorator
:vue-property-decorator
是基于 vue 组织里 vue-class-component 所做的拓展vuex-module-decorators
: 用 typescript 写 vuex 很好用的一个库组件声明
创建组件的方式变成如下
data 对象
Prop 声明
method
js 下是需要在 method 对象中声明方法,现变成如下
Watch 监听属性
onArrChanged(newValue: number[], oldValue: number[]) {}
computed 计算属性
allname 是计算后的值,name 是被监听的值
生命周期函数
emit 事件
使用 js 写法
vuex
在使用 store 装饰器之前,先过一下传统的 store 用法吧
然后开始使用
vuex-module-decorators
VuexModule
用于基本属性VuexModule 提供了一些基本属性,包括 namespaced,state,getters,modules,mutations,actions,context
@Module
标记当前为 modulemodule 本身有几种可以配置的属性:
@Mutation
标注为 mutation@Action
标注为 actiongetModule
得到一个类型安全的 store,module 必须提供 name 属性示例
我之前基于 ts+vue+element 构建了一个简单的中后台通用模板。
涵盖的功能如下:
里面对于在 vue 中使用 typescript 的各种场景都有很好的实践,大家感兴趣的可以参考一下,
https://github.com/easy-wheel/ts-vue
,当然不要吝惜你的 star!!!最后
你可以关注我的同名公众号【前端森林】,这里我会定期发一些大前端相关的前沿文章和日常开发过程中的实战总结。当然,我也是开源社区的积极贡献者,github地址
https://github.com/Cosen95
,欢迎star!!!The text was updated successfully, but these errors were encountered: