vue3中使用ts

一、选项式api中使用ts

使用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>

二、组件通信中使用ts

父子通信

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');
  }
})

三、组合式api中使用ts

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>

四、组合式api中组件通信使用ts

父子通信 => 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>

五、vueRouter中使用ts

路由中使用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

六、vuex中使用ts

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
}

七、Element Plus中使用ts

如果使用了volar插件 需要在tsconfig.json中通过compilerOptions.types指定全局组件类型
“types”: [“element-plus/global”]
这样配置完成之后写代码就有了友好的代码提示

你可能感兴趣的:(vue.js,前端,javascript)