Vue组合式API中如何使用TS
组合式API使用TS
组合式API中使用TS,要比选项式API中使用TS会更加的简单,不需要做过多的处理,只需要利用原生TS的能力就可以。并且组合式API都具备自动类型推断的能力,代码如下:
<script setup lang="ts">
import { computed, ref } from 'vue';
let count = ref(0);
let doubleCount = computed(()=> count.value * 2);
let handlClick = (n: number) => {
count.value += n;
}
</script>
count和doubleCount都会被自动推断出其对应的类型。如果想要进行更复杂的类型设置,需要自己手动进行类型注解,可利用泛型方式来实现。
<script setup lang="ts">
import { computed, ref } from 'vue';
interface List {
username: string
age: number
}
let count = ref<number|string>(0);
let list = ref<List[]>([]);
</script>
可以发现在组合式API中使用TS非常的简单。
Vue组合式API中组件通信使用TS
父子通信使用TS
主要利用的方案是,defineProps + 泛型
模式,defineProps
是组合式API中父子通信使用的主要方式,可以利用vue自带的方式进行类型注解。
<script setup lang="ts">
import { defineProps } from 'vue'
defineProps({
count: [Number, String]
});
</script>
同样会跟选项式API中有一个共同的问题,那么就是vue的这种方式用于限定类型还是比较有局限性的,再复杂的类型注解就要利用TS的能力来完成了,比如泛型的方式。
<script setup lang="ts">
import { defineProps } from 'vue'
interface Props {
count: number|string
list: {username: string; age: number}[]
}
defineProps<Props>();
</script>
这样就可以完成TS的类型注解,可以发现TS跟组合式API配合起来是非常简单的。
子父通信使用TS
主要利用的方案是defineEmits + 泛型
的方案,跟我们的父子通信差不太多。
<script setup lang="ts">
import { defineEmits } from 'vue'
interface Emits {
(e: 'get-data', payload: string): void
}
let emit = defineEmits<Emits>();
emit('get-data', 'hello'); // ✔
</script>
总结来说,TS跟组合式的配合要比跟选项式的配合更加的简单,所以推荐项目采用组合式API + TS来进行开发项目。
VueRouter路由如何使用TS
在安装脚手架的时候,可以选择自定义安装中,就会有路由的导入,这样在脚手架下就会有一个/router/index.ts
这个路由配置文件。
路由与TS
大多数情况下,路由都帮我们做了自动类型推断,那么路由给我们提供了很多内置的路由类型,如下:
- RouteRecordRaw -> 路由表选项类型
- RouteMeta -> 扩展meta的类型
- RouterOptions -> createRouter的配置类型
- RouteLocationNormalized -> 标准化的路由地址
- Router -> router实例的类型
RouteRecordRaw
是对路由表选项类型进行设置的,可以规范路由表的类型,需要我们自己进行类型注解。
// router/index.ts
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'home',
component: HomeView
}
]
我们经常要自己定义meta元信息的类型,做法如下:
declare module 'vue-router' {
interface RouteMeta {
// 是可选的
isAdmin?: boolean
// 每个路由都必须声明
requiresAuth: boolean
}
}
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'home',
component: HomeView,
meta: { requiresAuth: true }
}
]
引入declare module 'vue-router'
进行内部的合并处理,从而限定了meta原信息的类型,并且它是一种类型兼容性的方式。
RouterOptions
是createRouter的配置类型,这样在编写createRouter的时候就会自动进行类型推断。
// (alias) createRouter(options: RouterOptions): Router import createRouter
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
})
RouteLocationNormalized
是标准化的路由地址,在路由守卫和获取路由地址的情况下自动推断好。
// (parameter) to: RouteLocationNormalized
// (parameter) from: RouteLocationNormalized
router.beforeEach((to, from, next)=>{
});
Router
规范router实例的类型,在我们使用路由提供use函数,并产生router对象时自动推断产生。
<script setup lang="ts">
import { useRoute, useRouter } from 'vue-router';
// const router: Router
const router = useRouter();
</script>
这样当我们使用router对象的时候,会自动带有提示,并且我们不按照推断的形式进行设置属性,也会很好的给出提示错误。
包括具体方法的参数也会有类型限定,例如:router.push()
传递正确的参数才可以。
总结一下路由与TS:官方提供的路由模块已经提供了大量写好的类型,一般都是自动推断好的,除非有一些值是需要我们手动指定的,需要进行类型注解,例如:routes路由表。
Vuex状态管理如何使用TS
在安装脚手架的时候,可以选择自定义安装中,就会有状态管理的导入,这样在脚手架下就会有一个/store/index.ts
这个状态管理的配置文件。
状态管理与TS
vuex中如何跟TS配合呢?实际上还是会比较复杂的,有如下步骤:
- 导出key:export const key: InjectionKey<Store
> = Symbol() - 导入key:app.use(store, key)
- 重写useStore:export function useStore ()
首先第一步先对我们的状态管理配置文件进行类型注解,代码如下:
// store/index.ts
export interface State {
count: number
}
export default createStore<State>({
state: {
count: 1
}
})
为了让store.state能够有很好的提示效果,可以把一个key提供出去,并在main.ts中引入key值。
// store/index.ts
import type { InjectionKey } from 'vue'
import type { Store } from 'vuex'
export const key: InjectionKey<Store<State>> = Symbol()
// main.ts
import store, { key } from './store'
createApp(App).use(store, key).mount('#app')
最后一步就是对useStore进行改写,这样就可以利用到这个key给我们起到的一个提示作用。当我们再去使用useStore的时候就可以直接引入这个改造后的useStore了。
import { useStore as baseUseStore } from 'vuex'
export function useStore () {
return baseUseStore(key)
}
<script setup lang="ts">
import { useStore } from '@/store';
const store = useStore();
store.state.count
</script>
状态管理子模块中使用TS
在/store/index.ts
中使用TS基本没有太大问题了,但是如何在子模块中也可以使用TS呢?首先了解一下vuex给我们提供的一些自带的类型。
- MutationTree -> mutation类型注解
- GetterTree -> getter类型注解
- ActionTree -> Action类型注解
- Store -> store对象的类型
- StoreOptions -> createStore参数类型
像MutationTree
,ActionTree
,GetterTree
就是vuex提供的专门类型限定,同步方法、异步方法、计算属性的。所以我们可以直接去使用来控制状态管理的子模块。
// store/modules/users.ts
import type { MutationTree, ActionTree, GetterTree } from 'vuex'
import type { State } from '../index'
export interface UsersState {
username: string
age: number
}
const state: UsersState = {
username: 'xiaoming',
age: 20
};
const mutations: MutationTree<UsersState> = {};
const actions: ActionTree<UsersState, State> = {};
const getters: GetterTree<UsersState, State> = {};
export default {
namespaced: true,
state,
mutations,
actions,
getters
}
下面是需要把子模块导出,跟主模块进行合并处理。
// store/index.ts
import users from './modules/users'
import type { UsersState } from './modules/users'
export interface State {
count: number
}
interface StateAll extends State {
users: UsersState
}
export const key: InjectionKey<Store<StateAll>> = Symbol()
Element Plus中如何使用TS
Element Plus中使用TS
Element Plus默认就是高度集成TS的支持,不过为了更好的能让Element Plus进行提示效果,还是需要做一些处理配置的。
如果您使用 Volar,请在 tsconfig.json 中通过 compilerOptions.types 指定全局组件类型"types": ["element-plus/global"]
// tsconfig.json
"types": [
"webpack-env",
"element-plus/global"
]
配置好后,当输入<
的时候,就会自动带有提示组件功能,以及组件属性与属性值的提示效果。
这里需要注意,由于Volar插件更新比较快,如果不能很好进行提示的话,可以把Volar插件降级到1.0.0这个版本。
除了提示外,Element Plus默认带有的类型都可以在Vue项目中引入,并进行使用,例如表单控件,代码如下:
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
const ruleFormRef = ref<FormInstance>()
const rules = reactive<FormRules>({
})
const submitForm = async (formEl: FormInstance | undefined) => {
}
FormInstance
用于定义表单实例的类型,FormRules
用于定义表单规则的类型等。