Ref
基本
ref是可以接收一个泛型的
如果不传东西,默认就是any
组件实例
一般是用 ref 获取组件实例,然后调用组件里面的方法
但是传null的话,泛型默认就是null,ts认为null是没有任何东西的,因此没办法使用组件内的方法
解决方法是传入下面的:
泛型里面要传入的,是一个类型,而你不能这样传 ref<组件名>,因为组件名,不是类型,只是一个类的实例。
要获取这个组件的类型,可以通过 InstanceType
简单的说,就是这样获取一个组件对应的类型。
Props
在.vue文件,使用Vue3 的 setup语法糖,标注props属性的类型,需要这样:
<script setup lang="ts">
import { PropType } from "vue"
/** 定义父组件可以传入的 props */
const props = defineProps({
columnProps: {
type: Object as PropType<youTypes>, // 这里可以放入你的类型
required: true
}
})
</script>
Vuex
根
vuex基本都是推导出来的,但最好指定一个接口类型
模块
定义模块
但是看到有报错,原因是Module要求你传入2个泛型
第一个S是state的类型
第二个是根的state的类型
两个类型,都可以自己定义接口就可以了。
你先写state里的变量,然后接口写上对应的类型就可以了。
如果类型太多,可以单独拎出来写在对应的 types.ts 文件里面(名字随你自己定),表示这里存放类型
然后导出这个接口
/** VueX 中 登录模块的 state 类型 */
export interface LoginState {
userName:String
}
最后引入
import { Module } from "vuex";
import { IRootState } from "../../types";
import { LoginState } from "./type";
const loginModule:Module<LoginState,IRootState> = {
namespaced:true,
state(){
return {
userName:""
}
}
}
export default loginModule
useStore() 重新封装
问题的产生
vuex对TS的支持不是很好,直接用useStore的时候,类型是any,同时也没有对应的代码提示
即便你像下图这样传入一个泛型,也还是有点问题,而且还要去引入一个类型
重新封装useStore
要改善这个问题,可以对useStore进行重新封装。
1、定义一个storeType类型,这类型是联合了 vuex根state接口,和模块中state的接口
// .src/store/types.ts
/** 定义 Vuex 根接口 */
export interface IRootState {
/** 是否显示全屏加载中 */
isSpinning:boolean
}
/** 定义 Vuex 模块接口 */
export interface IRootWithModules {
// 以后这里定义各个模块的state变量
}
/** 定义 Vuex 总接口,为 根接口 & 模块接口 */
export type IStoreType = IRootState & IRootWithModules
2、store/index.ts 中,引入storeType类型,并导出一个我们封装的useStore( ),它的返回值是store类型,泛型是那个联合类型
// =================== 1、引入 ===================
// 引入 vuex 的 createStore创建实例,和 useStore 使用Vuex方法
import { createStore,useStore as useVuexStore } from "vuex"
// 引入 Vuex实例类型
import type { Store } from "vuex"
// 引入我们定义的 根类型,和Vuex根+模块类型
import type { IRootState,IStoreType } from "./types";
// =================== 2、定义 Vuex 根 ===================
/** Vuex 根 */
const store = createStore<IRootState>({
state() {
return {
isSpinning: true
}
}
})
export default store
// =================== 3、重新定义 useStore 方法 ===================
// 后面在 .vue 文件中,需要通过 import { useStore } from "@/store/" ,引入我们新定义的useStore,才能正确显示store及其模块的类型
/** 新的 useStore 方法 */
export function useStore():Store<IStoreType>{
return useVuexStore()
}
3、在要使用的组件中,引入我们封装的useStore,就有正确的提示了
4、如果后面还有什么模块,直接加到模块类型里面就可以了
模块
1、需要先定义模块里面state的类型(接口或类,优先接口)
2、模块中,引入类型 Module 和 根的state类型(根的也是自己定义的)
然后模块的类型就是 Module<泛型>,泛型里面第一个参数就是模块的state类型,第二个参数是vuex根的state类型
3、vuex根文件,放入模块
4、vuex 的useStore重新封装的,加入新的模块的类型,让别的地方可以自动识别