使用 typescript ,提升 vue 项目的开发体验(1)
此文已由作者张汉锐授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
前言:对于我们而言,typescript 更像一个工具
官方指南
从 vue2.5 之后,vue 对 ts 有更好的支持。根据官方文档,vue 结合 typescript ,有两种书写方式:
Vue.extend
import Vue from 'vue'
const Component = Vue.extend({ // type inference enabled
})
Class-style Vue Components
import Vue from 'vue'
import Component from 'vue-class-component' // The @Component decorator indicates the class is a Vue component
@Component({ // All component options are allowed in here
template: '<button @click="onClick">Click!</button>'
})
export default class MyComponent extends Vue { // Initial data can be declared as instance properties
message: string = 'Hello!' // Component methods can be declared as instance methods
onClick (): void { window.alert(this.message)
}
}
理想情况下,Vue.extend 的书写方式,是学习成本最低的。在现有写法的基础上,几乎 0 成本的迁移
// 现在常见的写法export default { // your code }
但「理想丰满,现实骨感」,问题出在:
Vue.exend 在和 vuex 和 mixins 结合使用的时候,无法发挥 ts 的作用,vuex 和 mixins 会在项目中大量使用,这个问题不能忽视。
Vue.extend + vuex + mixins 问题的介绍
Vue.extend + vuex 的问题
由于 vuex 使用 mapState, mapActions 等方法的时候,通过字符串形式做映射,这个过程中,丢失了类型信息。下面的 gif 可以看到,整个过程中:
无法做代码提示
无法对对应的 actions 和 state 做类型声明,使得类型检查生效
无法使用重构
显然,如果只有一部分的方法和属性得到了代码提示和类型检查,就是失去了使用 typescript 意义。
在 Vue.extend + vuex 写法下,这个问题暂时没有解决方案。
Vue.extend + mixins 的问题
同样的问题,在 mixin 中定义的方法,不会被 typescript 识别到,下面 gif 可以看到,不仅仅「代码提示」「类型检查」「代码重构」没有工作,甚至因识别不到 test 而报错
Class-Style Components
那么就剩下 Class-Style Components 方案。当然,这个方案需要做额外的工作才能够让「vue 全家桶 + ts」良好的工作。
原理:将属性直接挂载在 class 上,使得 typescript 能够良好的进行「代码提示」和「类型检查」。然后再通过装饰器将属性转成 vue 上的属性。
例如 @Prop, @Watch, @Action 等装饰器,将属性做相应的转换成 props, watch, mapActions 里面的值,具体后面例子展示。
vue-class-component
这里库提供最基础的 vue 装饰器:@Component 。其他的 vue 装饰器库,都在这个库的基础上做扩展和修改。看看官网的例子:
import Vue from 'vue'import Component from 'vue-class-component'// @Component 会将 MyComponent 中的属性,转换成 vue 对应的属性@Component({ // Vue 所有的属性都可以在这里声明,一般用到的比较少
template: '<button @click="onClick">Click!</button>'})
export default class MyComponent extends Vue { // @Component 将 message 转成成 data
message: string = 'Hello!'
// @Component 会将这里的 getter 属性,转换成 computed
get name(){ return 'anders'
} // @Component 识别到 created 是声明周期关键字,不做处理
created(){} // @Component 识别到 onClick 不是关键字,将它转成 methods
onClick (): void { window.alert(this.message)
}
}
vue-property-decorator
这个库提供了:
@Emit
@Inject
@Model
@Prop
@Provide
@Watch
其中常用的: @Prop,@Watch,@Emit。 看例子:
import { Component, Emit, Inject, Model, Prop, Provide, Vue, Watch } from 'vue-property-decorator'const s = Symbol('baz')
@Component
export class MyComponent extends Vue {
@Emit()
addToCount(n: number){ this.count += n }
@Emit('reset')
resetCount(){ this.count = 0 }
@Prop()
propA: number
@Prop({ default: 'default value' })
propB: string
@Prop([String, Boolean])
propC: string | boolean
@Watch('child')
onChildChanged(val: string, oldVal: string) { }
@Watch('person', { immediate: true, deep: true })
onPersonChanged(val: Person, oldVal: Person) { }
}
上面的使用就相当于:
const s = Symbol('baz')
export const MyComponent = Vue.extend({
name: 'MyComponent',
props: {
checked: Boolean,
propA: Number,
propB: {
type: String, default: 'default value'
},
propC: [String, Boolean],
},
methods: {
addToCount(n){ this.count += n this.$emit("add-to-count", n)
},
resetCount(){ this.count = 0
this.$emit("reset")
},
onChildChanged(val, oldVal) { },
onPersonChanged(val, oldVal) { }
},
watch: { 'child': {
handler: 'onChildChanged',
immediate: false,
deep: false
}, 'person': {
handler: 'onPersonChanged',
immediate: true,
deep: true
}
}
})
更加全面的用法参考文档:vue-property-decorator
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 iOS安装包瘦身(上篇)
使用 typescript ,提升 vue 项目的开发体验(1)的更多相关文章
- 使用 typescript ,提升 vue 项目的开发体验(2)
此文已由作者张汉锐授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. vuex-class 提供了和 vuex 相关的全部装饰器,从而解决了上面 Vue.extend + vue ...
- TypeScript编写Vue项目结构解析
使用TypeScript编写Vue项目也已经有了一段时间,笔者在刚刚使用TypeScript时候也是很茫然,不知道从何下手,感觉使用TypeScript写项目感觉很累赘并不像JavaScript那么灵 ...
- vue项目的开发
vue项目的开发 我们已经通过命令行创建了一个vue项目,并且打开了这个项目.下面是这个文件的src文件夹,这个文件夹放了整个项目的核心代码. 一.vue文件的用处简介. 1.assets文件夹,用来 ...
- 如何加快Vue项目的开发速度
如何加快Vue项目的开发速度 本文摘自奇舞周刊,侵权删. 现如今的开发,比如内部使用的管理平台这种项目大都时间比较仓促.实际上来说,在使用了webpack + vue 这一套来开发的话已经大大了提高了 ...
- 基于Typescript的Vue项目配置国际化
基于Typescript的Vue项目配置国际化 简介 使用vue-i18n插件对基于Typescript的vue项目配置国际化,切换多种语言, 配合element-ui或者其他UI库 本文以配置中英文 ...
- 教你搭建基于typescript的vue项目
自尤大去年9月推出vue对typescript的支持后,一直想开箱尝试,对于前端sr来说,vue的顺滑加上ts的面向对象,想着就非常美好~ 终于在两个月前,找到了个机会尝试了一把vue+ts的组合. ...
- 手动搭建webpack + vue项目之初体验
在使用vue做开发时,大部分人只会使用官方提供的脚手架搭建项目,脚手架虽然很好用,但想要成为一名优秀的前端开发者,webpack这一道坎是绕不开的,所以我们要学会脱离脚手架,利用webpack手动搭建 ...
- 使用TypeScript创建Vue项目
Vue的灵活性总是让代码看起来非常洗练,对TypeScript来说也是一种挑战, 好在Vue对TypeScript进行了一次全方位的适配. 相对于React严谨的代码,Redux啰嗦的样板代码,Vue ...
- 加快Vue项目的开发速度
巧用Webpack Webpack是实现我们前端项目工程化的基础,但其实她的用处远不仅仅如此,我们可以通过Webpack来帮我们做一些自动化的事情.首先我们要了解require.context()这个 ...
随机推荐
- AngularJS:template2
ylbtech-AngularJS: 1.返回顶部 1. 2. 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 1. 2. 6.返回顶部 作者:ylbtech出处:h ...
- linux c++ rabbitMq Demo
1.在vs上实现远程调试Linux c++程序:https://www.jianshu.com/p/8b51a795cb92. 2.调试需要c++11,升级redhat上的gcc版本,虚拟机gcc版本 ...
- DIKW模型与数据工程
DIKW 体系 DIKW体系是关于数据.信息.知识及智慧的体系,可以追溯至托马斯·斯特尔那斯·艾略特所写的诗--<岩石>.在首段,他写道:“我们在哪里丢失了知识中的智慧?又在哪里丢失了信息 ...
- Python 面向对象的进阶
类的成员 类的成员可以分为三大类 : 字段 , 方法 和 属性 注 : 所有的成员中,只有普通字段的内容保存对象中, 即 : 根据此类创建了对象,在内存就有多少个普通字段. 而其他的成员,则 ...
- C#带百分比的进度条
功能需求: 如果程序中会执行一个耗时的计算过程,我想在用户点击按钮后,弹出一个进度条窗口,显示正在执行的进度(最好能带有百分比),执行完成后,进度条窗口关闭,回到主程序窗口. 在关闭子窗口之前父窗体不 ...
- ECommon.Dapper 轻量级的dapper扩展
我们都知道Dapper这个orm框架,但是我们也知道他的扩展目前没有特别好的,今天我就推荐一个轻量级的很方便使用的一个扩展叫做 ECommon.Dapper,它是ECommon的一个类库,关于ECom ...
- Hibernate 实体对象三种状态 :自由,持久,游离
实体对象的状态及转化: 有了上面关于Hibernate缓存的知识,我们再来介绍实体对象的状态就非常容易理解了. A:自由态对象: 当我们通过Java的new关键字来生成一个实体对象时,这时这个实体对象 ...
- CXF动态客户端如何优化JaxWsDynamicClientFactory.createClient -- 慢
在CXF动态创建客户端时,如下: JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance(); Client ...
- 更新solrcloud+zookeeper的配置文件,要reload collection
1.用的lib下的solr-core-4.3.1jar中的ZkCLI工具,命令在solr(web发布的)同级目录下运行. (1)upconfig 更新配置文件命令 java -classpath ./ ...
- linux su su -
本人以前一直习惯直接使用root,很少使用su,前几天才发现su与su -命令是有着本质区别的! 大部分Linux发行版的默认账户是普通用户,而更改系统文件或者执行某些命令,需要root身份才能进行, ...