使用defineComponent定义组件 => 启用类型推导
<template>
<div>
<h2>Hello 01</h2>
<button @click="handleClick(5)">点击</button>
{{ count }}, {{ doubleCount }}
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
type Count = number | string;
interface List {
username: string
age: number
}
export default defineComponent({
data(){
return {
count: 0 as Count,
list: [] as List[]
}
},
mounted(){
this.count = 2
this.list.push({
username: 'xiaoming',
age: 20
});
},
computed: {
doubleCount(): number|string{
if(typeof this.count === 'number'){
return this.count * 2;
}
else{
return this.count;
}
}
},
methods: {
handleClick(n: number){
if(typeof this.count === 'number'){
this.count += n;
}
}
}
});
</script>
<style scoped>
</style>
父子通信
import { defineComponent } from 'vue'
import type { PropType } from 'vue'
interface List {
username: string
age: number
}
export default defineComponent({
props: {
count: [Number, String],
list: Object as PropType<List[]>
},
//emits: ['get-data'],
emits: {
'get-data'(payload: string){ return payload.length > 0 }
},
mounted(){
this.$emit('get-data', 'hello');
}
})
compositionApi默认启用了类型检测,定义基本类型数据可以使用泛型的形式绑定类型
<template>
<div>
<h2>Hello 03</h2>
<button @click="handlClick(5)">点击</button>
{{ count }}, {{ doubleCount }}
</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
// let count = ref(0);
// count.value = 'hello';
// interface List {
// username: string
// age: number
// }
// let list = ref([]);
// list.value.push({
// username: 'xiaoming',
// age: 20
// });
let count = ref(0);
let doubleCount = computed(()=> count.value * 2);
let handlClick = (n: number) => {
count.value += n;
}
</script>
<style scoped>
</style>
父子通信 => defineProps + 泛型
子父通信 => defineEmits + 泛型
<template>
<div>
Head Component
</div>
</template>
<script setup lang="ts">
// import { defineProps, defineEmits } from 'vue'
// 1.
// defineProps({
// count: [Number, String]
// });
//2.
interface Props {
count: number|string
list: {username: string; age: number}[]
}
interface Emits {
(e: 'get-data', payload: string): void
}
defineProps<Props>();
let emit = defineEmits<Emits>();
emit('get-data', 'hello');
</script>
<style scoped>
</style>
路由中使用ts 路由表的类型和路由中的meta类型需要手动处理一下,其他地方(createRouter、useRoute、useRouter)默认已经处理好了
import { createRouter, createWebHistory } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'
import HomeView from '../views/HomeView.vue'
declare module 'vue-router' {
interface RouteMeta {
// 是可选的
isAdmin?: boolean
// 每个路由都必须声明
requiresAuth: boolean
}
}
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'home',
component: HomeView,
meta: { requiresAuth: true }
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
})
// router.beforeEach((to, from, next)=>{
// });
export default router
import { createStore, useStore as baseUseStore } from 'vuex'
import users from './modules/users'
import type { UsersState } from './modules/users'
import type { Store } from 'vuex'
import type { InjectionKey } from 'vue'
export interface State {
count: number
}
// 整合其他模块的类型
interface StateAll extends State {
users: UsersState
}
// 这个key是为了能够在组件中使用vuex能够有正确的类型推断
// 还要在main.ts中 注册vuex插件时传递给vue
// import store, { key } from './store'
// app.use(store, key)
export const key: InjectionKey<Store<StateAll>> = Symbol()
export function useStore () {// 重写useStore函数 为了避免每次使用都要传key
return baseUseStore(key)
}
export default createStore<State>({
state: {
count: 1
},
getters: {
doubleCount(state){
return state.count * 2;
}
},
mutations: {// 默认具有类型推断
// add(state, payload: number){
// }
},
actions: {
},
modules: {
users
}
})
// 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> = {// 其他模块中需要手动引入MutationTree
// change(state){
// }
};
const actions: ActionTree<UsersState, State> = {};
const getters: GetterTree<UsersState, State> = {
doubleAge(state){
return state.age * 2;
}
};
export default {
namespaced: true,
state,
mutations,
actions,
getters
}
如果使用了volar插件 需要在tsconfig.json中通过compilerOptions.types指定全局组件类型
“types”: [“element-plus/global”]
这样配置完成之后写代码就有了友好的代码提示