有人说:用过ts的人的反应,只有真香和真tm香
Git
git clone https://github.com/DrBallon/TodoList.git --branch vue
搭建框架
因为暂时不擅长各种插件和配置,所以基础框架用vue-cli一梭子搞定
vue-cli 版本 4
vue create todolist-0.22
//1.Please pick a preset: Manually select features
选择"Manually select features" 手动选择要用的组件
//2.Check the features needed for your project:
选择 "Typescript" "Vuex" "CSS-processors"(我用了sass)
//3.Choose a version of Vue.js that you want to start the project with
选择 vue 2.x
//4.Use class-style component syntax?
//选择是否使用基于类的 API
选择 y 确定
//5.Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)?
选择 y 确定
vuex
个人喜欢先从数据搞起,先重构vuex部分。
更改部分
//以下部分类似,仅仅需要设置参数的类型以及微调
index
mutations
state
//仅仅是导出字符串,只需要把文件后缀名修改
mutation_types
//actions 因为tytypescript开启严格模式对格式要求较高,此处改变较多
actions
//新增部分,保存与vuex相关的各种数据格式接口
IFs.ts
mutations
index,mutations,state类似,以mutations为例子
//js写法
getGroups(state) {},
//给函数参数添加类型
getGroups(state: State) {},
//ps.State保存在IFs.ts里,通过import引入
//mutations.ts
import {State} from './IFs'
//IFs.ts
export interface State{
...
}
actions
//普通js写法
const changeMode = ({commit},newMode)=> commit('CHANGE_MODE',newMode)
一开始会不知道该从哪里下手修改,这里提供一个思路
//记住action的方法类型名为 Action<当前State类型,根State类型>
//如果store没有分模块,那么直接就写成 Action<当前State类型,当前State类型> 也可以
//写成 Action<State,any> 也可以(使用了tslint会显示warn)
//那么
import {Action} from 'vuex'
const changeMode:Action<State,any>=({commit},newMode)=> commit('CHANGE_MODE',newMode)
//按住ctrl,鼠标左键点击 Action,会跳到类型声明
//显示 export type Action<S, R> = ActionHandler<S, R> | ActionObject<S, R>;
//继续点击 ActionHandler 跳转到它的定义
//定义为 export type ActionHandler<S, R> = (this: Store<R>, injectee: ActionContext<S, R>, payload?: any) => any;
//这就是action函数的格式要求。查看参数要求,第一个this为当前对象,忽视。第二个injectee就是我们平时使用的commit的父类。第三个payload自然就是参数了。
//跳转到injectee的格式ActionContext的声明
//看到以下内容。可以看到属性中的commit
/*
export interface ActionContext<S, R> {
dispatch: Dispatch;
commit: Commit;
state: S;
getters: any;
rootState: R;
rootGetters: any;
}
*/
//接下来就可以写了
//首先是最直接的,从vuex 获取 ActionContext
import { ActionContext } from 'vuex';
...
const changeMode: Action<State, State> = (context: ActionContext<State, State>, newMode: number) =>
context.commit('CHANGE_MODE', newMode);
//测试,搞定
//当然也可以秀一波解构赋值,因为context内我们只使用到了Commit。当然也要引入Commit
const changeMode: Action<State, State> = (context: { commit: Commit }, newMode: number) =>
context.commit('CHANGE_MODE', newMode);
以上就是vuex的主要难点,剩下的就是为变量写接口,分离,引入,测试之类的事情了。
组件
以一个组件为例子
组件结构
Group
props
group
data
groupData
showList
computed
curMode
methods
toggle
hook
created
watch
group
因为是把已有的项目更改为ts,所以模板部分和样式部分原封不动的复制
修改部分为script标签
1.因为我这次选择的是基于类的写法。所以从插件中获取基类。
import { Vue, Component } from 'vue-property-decorator';
2.script标签修改成ts
<script lang="ts">
3.添加@Component,组件名,如果有子组件也在此引入
@Component({
name:"xxx",
components:{
//子组件
}
})
4.添加props。因为貌似vue2.x对ts支持并不完全。props是以创建一个带有props的父类,再继承它来实现的
const XxxProps = Vue.extend({
props: ['group'],
})
//并修改导出。如果没有props 那么,extends Vue
export default class Xxx extends XxxProps{}
//ps,如果要进行prop类型检验,且类型为自定义接口类型
import { Group } from '@/store/state';
import { PropType } from 'vue';
const ItemProps = Vue.extend({
props: {
item: Object as PropType<Group>,
},
});
5.data
data(){
return{
aaa:10,
bbb:11
}
}
改为:
export default class Xxx extends XxxProps{
private groupData = 10
private showList = 11
}
6.methods,把内部函数直接提出来,
methods:{
toggle(){}
}
改为:
toggle(){}
7.computed
computed:{
//get
curMode(){},
//假设有 set YYY
YYY(){},
}
改成:
get curMode(){}
set YYY(){}
8.钩子不需要修改,把逗号去掉就行了
created()
9.watch
watch:{
aaa(){}
}
改成:
@Watch('aaa')
onAaaChanged(newVal){}
ps.需要从 vue-property-decorator 引入Watch
组件格式
<script lang="ts">
import { Vue, Component, Watch } from 'vue-property-decorator';
import { PropType } from 'vue';
import Item from '@/components/Item.vue';
import { List } from '@/store/IFs';
const GroupProps = Vue.extend({
props: {
group: Object as PropType<List>,
},
});
@Component({
name: 'Group',
components: {
Item,
},
})
export default class Group extends GroupProps {
private groupData: List = {};
private showList = true;
get curMode() {}
del() {}
toggle() {}
created() {}
@Watch('group')
onGroupChange(newValue: List) {}
}
</script>
相关文档
基于类的vue api 基础
https://class-component.vuejs.org/guide/class-component.html#data
上面的扩展(@watch之类的)
https://www.npmjs.com/package/vue-property-decorator
ts 文档
https://www.tslang.cn/docs/home.html