Vue 3 组合式 API 与 TypeScript 集成

Vue 3 的组合式 API 提供了更好的 TypeScript 支持,通过 defineComponent 和泛型可以明确类型推断。以下是一个基础示例:

<script setup lang="ts">
import { ref, computed } from 'vue'

// 类型化响应式数据
const count = ref<number>(0)
const double = computed<number>(() => count.value * 2)

// 类型化函数
const increment = (step: number): void => {
  count.value += step
}
</script>

Pinia 状态管理方案

Pinia 是 Vue 官方推荐的状态管理库,专为组合式 API 设计,具有完整的 TypeScript 支持。

安装与基础配置

npm install pinia

定义 Store

// stores/counter.ts
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0 as number,
    name: 'Counter' as string
  }),
  getters: {
    double: (state) => state.count * 2
  },
  actions: {
    increment(step: number) {
      this.count += step
    }
  }
})

组件中使用

<script setup lang="ts">
import { useCounterStore } from '@/stores/counter'

const counter = useCounterStore()
</script>

Vuex 状态管理方案

Vuex 4 虽然支持 Vue 3,但在 TypeScript 集成上需要更多手动类型声明。

安装与基础配置

npm install vuex@next

定义 Store

// store/index.ts
import { createStore } from 'vuex'

interface State {
  count: number
  name: string
}

export default createStore({
  state: (): State => ({
    count: 0,
    name: 'Counter'
  }),
  getters: {
    double: (state) => state.count * 2
  },
  mutations: {
    INCREMENT(state, payload: number) {
      state.count += payload
    }
  },
  actions: {
    increment(context, payload: number) {
      context.commit('INCREMENT', payload)
    }
  }
})

组件中使用

<script setup lang="ts">
import { useStore } from 'vuex'

const store = useStore<{
  count: number
  name: string
}>()
</script>

方案对比

Pinia 优势

  • 专为组合式 API 设计,无需嵌套结构
  • 完整的 TypeScript 支持,自动推断类型
  • 更简洁的 API,减少样板代码
  • 模块化设计,无需手动命名空间

Vuex 适用场景

  • 需要严格的 Flux 架构规范
  • 已有 Vuex 大型项目迁移
  • 需要插件系统(如持久化存储)

类型安全增强实践

Pinia 高级类型

interface UserState {
  name: string
  age: number
}

export const useUserStore = defineStore('user', {
  state: (): UserState => ({
    name: 'Alice',
    age: 30
  })
})

Vuex 类型增强

// store/types.ts
export interface RootState {
  version: string
}

// 扩展模块类型
declare module 'vuex' {
  export interface Store<S> {
    state: S & RootState
  }
}

更多推荐