Vue3 + Vite + Pinia + TypeScript 项目完整搭建与实战指南

0 阅读4分钟

前言

这是一套Vue3 现代化技术栈,也是目前企业开发最主流的组合:

  • Vue3:渐进式前端框架(组合式 API)
  • Vite:极速开发构建工具
  • Pinia:Vue 官方状态管理库(替代 Vuex)
  • TypeScript:类型安全的 JavaScript 超集

本文带你从零搭建项目,包含基础配置、Pinia 实战、TS 规范,可直接用于生产开发。

一、环境准备

确保本地已安装:

  1. Node.js 16+ 版本
  2. npm /yarn/pnpm(推荐 pnpm)

二、快速创建 Vite + Vue3 + TS 项目

打开终端,执行创建命令:

# npm
npm create vite@latest

# yarn
yarn create vite

# pnpm (推荐)
pnpm create vite

项目初始化步骤

  1. 输入项目名称(如 vue3-pinia-ts
  2. 框架选择:Vue
  3. 变体选择:Vue + TypeScript
  4. 进入项目、安装依赖、启动项目:
cd vue3-pinia-ts
pnpm install
pnpm dev

启动成功后,打开 http://localhost:5173 即可看到默认页面。

三、安装并配置 Pinia

Pinia 是 Vue3 官方状态管理,支持 TS、模块化、热更新,使用极简。

1. 安装 Pinia

pnpm add pinia

2. 全局注册 Pinia

打开 src/main.ts,注册 Pinia:

import { createApp } from 'vue'
import { createPinia } from 'pinia' // 引入 Pinia
import App from './App.vue'
import './style.css'

const app = createApp(App)

app.use(createPinia()) // 注册 Pinia
app.mount('#app')

四、Pinia + TypeScript 实战(核心)

我们创建一个用户状态模块,演示 Pinia 标准用法:stategettersactions

1. 创建类型定义

新建 src/types/user.ts,定义 TS 接口:

// 用户信息类型约束
export interface UserInfo {
  id: number
  name: string
  age: number
}

// 全局状态类型
export interface UserState {
  userInfo: UserInfo | null
  token: string
}

2. 创建 Pinia Store

新建 src/stores/user.ts,编写状态管理:

import { defineStore } from 'pinia'
import type { UserState } from '@/types/user'

// 定义 Store,唯一 ID:user
export const useUserStore = defineStore('user', {
  // 状态:必须是函数,TS 自动推导类型
  state: (): UserState => ({
    userInfo: null,
    token: ''
  }),

  // 计算属性:类似 computed,有缓存
  getters: {
    // 获取用户名称
    getUserName: (state) => state.userInfo?.name || '未登录',
    // 获取用户年龄
    getUserAge: (state) => state.userInfo?.age || 0
  },

  // 方法:类似 methods,支持同步/异步,修改 state
  actions: {
    // 登录:设置 token 和用户信息
    login(userData: UserState) {
      this.token = userData.token
      this.userInfo = userData.userInfo
    },

    // 退出登录:重置状态
    logout() {
      this.$reset()
    },

    // 异步更新用户信息(模拟接口请求)
    async updateUserInfo() {
      return new Promise<void>((resolve) => {
        setTimeout(() => {
          this.userInfo = {
            id: 1,
            name: 'Vue3+Pinia开发者',
            age: 25
          }
          resolve()
        }, 500)
      })
    }
  }
})

3. 配置路径别名(@ 符号)

import 更简洁,支持 @/stores/xxx

① 修改 vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      // 配置 @ 指向 src 目录
      '@': path.resolve(__dirname, './src')
    }
  }
})
② 修改 tsconfig.json

让 TS 识别别名:

{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

五、在 Vue 组件中使用(组合式 API)

打开 src/App.vue,测试 Pinia 状态管理:

<template>
  <div class="container">
    <h2>Vue3 + Vite + Pinia + TS 实战</h2>
    <p>用户名:{{ userStore.getUserName }}</p>
    <p>年龄:{{ userStore.getUserAge }}</p>
    <p>Token:{{ userStore.token || '无' }}</p>

    <button @click="handleLogin">模拟登录</button>
    <button @click="handleAsyncUpdate">异步更新信息</button>
    <button @click="handleLogout">退出登录</button>
  </div>
</template>

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

// 实例化 Store
const userStore = useUserStore()

// 模拟登录
const handleLogin = () => {
  userStore.login({
    token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
    userInfo: {
      id: 1,
      name: '张三',
      age: 24
    }
  })
}

// 异步更新用户信息
const handleAsyncUpdate = async () => {
  await userStore.updateUserInfo()
  alert('信息更新成功!')
}

// 退出登录
const handleLogout = () => {
  userStore.logout()
}
</script>

<style scoped>
.container {
  max-width: 600px;
  margin: 50px auto;
  padding: 20px;
  text-align: center;
}
button {
  margin: 0 10px;
  padding: 8px 16px;
  cursor: pointer;
}
</style>

六、Pinia 数据持久化(常用插件)

刷新页面后 Pinia 数据会丢失,安装持久化插件自动保存到 localStorage:

pnpm add pinia-plugin-persistedstate

注册并使用

修改 src/main.ts

import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate) // 注册持久化

在 Store 中开启持久化:

export const useUserStore = defineStore('user', {
  // ...其他配置
  persist: true // 开启持久化
})

七、项目目录结构(推荐)

vue3-pinia-ts/
├── src/
│   ├── assets/       # 静态资源
│   ├── components/    # 公共组件
│   ├── stores/        # Pinia 状态管理
│   │   └── user.ts    # 用户模块
│   ├── types/         # TS 类型定义
│   │   └── user.ts
│   ├── App.vue        # 根组件
│   └── main.ts        # 入口文件
├── vite.config.ts     # Vite 配置
└── tsconfig.json      # TS 配置

八、JavaScript 版本(无需 TS)

如果不使用 TypeScript,只需:

  1. 创建项目时选择 Vue + JavaScript
  2. 去掉所有 type 类型定义
  3. 代码语法完全一致,仅无类型约束

JS 版 Store 示例:

import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    userInfo: null,
    token: ''
  }),
  getters: {
    getUserName: (state) => state.userInfo?.name || '未登录'
  },
  actions: {
    login(userData) {
      this.token = userData.token
      this.userInfo = userData.userInfo
    }
  }
})

总结

  1. Vite 极速创建 Vue3 + TS 项目,开发体验极佳
  2. Pinia 用法简单:defineStorestate/getters/actions
  3. TypeScript 提供类型安全,减少线上 bug
  4. 全套方案企业级可用,支持路由、axios、持久化等扩展

——个人观点 · 仅供参考——