Vue3 + Vite + Ant Design Vue + Axios + Pinia 脚手架搭建

724 阅读3分钟

Vue3 + Vite + Ant Design Vue + Axios + Pinia 脚手架搭建指南

下面是一个完整的 Vue3 项目脚手架配置,使用 TypeScript 编写,包含所有必要的配置文件和基础代码。

项目结构

text

my-vue-project/
├── public/
├── src/
│   ├── api/
│   ├── assets/
│   ├── components/
│   ├── layouts/
│   ├── router/
│   ├── stores/
│   ├── utils/
│   ├── views/
│   ├── App.vue
│   ├── main.ts
│   └── vite-env.d.ts
├── .env
├── .env.development
├── .env.production
├── .eslintrc.js
├── .gitignore
├── package.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts

1. package.json

json

{
  "name": "my-vue-project",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc && vite build",
    "preview": "vite preview",
    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
  },
  "dependencies": {
    "@ant-design/icons-vue": "^7.0.0",
    "ant-design-vue": "^4.0.0",
    "axios": "^1.6.2",
    "pinia": "^2.1.7",
    "vue": "^3.3.0",
    "vue-router": "^4.2.5"
  },
  "devDependencies": {
    "@types/node": "^20.10.0",
    "@vitejs/plugin-vue": "^4.5.0",
    "@vue/eslint-config-prettier": "^8.0.0",
    "@vue/eslint-config-typescript": "^11.0.3",
    "eslint": "^8.55.0",
    "eslint-plugin-vue": "^9.17.0",
    "prettier": "^3.1.0",
    "typescript": "^5.3.0",
    "vite": "^5.0.0",
    "vue-tsc": "^1.8.11"
  }
}

2. vite.config.ts

typescript

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src')
    }
  },
  server: {
    port: 3000,
    open: true,
    cors: true,
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^/api/, '')
      }
    }
  },
  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true,
        modifyVars: {
          'primary-color': '#1890ff',
          'link-color': '#1890ff',
          'border-radius-base': '4px'
        }
      }
    }
  }
})

3. tsconfig.json

json

{
    "compilerOptions": {
        "target": "ESNext",
        "useDefineForClassFields": true,
        "module": "ESNext",
        "moduleResolution": "Node",
        "strict": true,
        "jsx": "preserve",
        "sourceMap": true,
        "resolveJsonModule": true,
        "isolatedModules": true,
        "esModuleInterop": true,
        "lib": [
            "ESNext",
            "DOM"
        ],
        "skipLibCheck": true,
        "baseUrl": ".",
        "paths": {
            "@/*": [
                "src/*"
            ]
        }
    },
    "include": [
        "src/**/*.ts",
        "src/**/*.d.ts",
        "src/**/*.tsx",
        "src/**/*.vue"
    ]
}

4. .env 文件

.env (通用环境变量)

text

VITE_APP_TITLE=My Vue App
VITE_APP_BASE_API=/api

.env.development (开发环境)

text

NODE_ENV=development
VITE_APP_ENV=development
VITE_APP_BASE_URL=http://localhost:3000

.env.production (生产环境)

text

NODE_ENV=production
VITE_APP_ENV=production
VITE_APP_BASE_URL=https://production.example.com

5. 源代码文件

src/main.ts

typescript

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'
import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/reset.css'

const app = createApp(App)

app.use(createPinia())
app.use(router)
app.use(Antd)

app.mount('#app')

src/vite-env.d.ts

typescript

/// <reference types="vite/client" />

declare module '*.vue' {
  import { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

interface ImportMetaEnv {
  readonly VITE_APP_TITLE: string
  readonly VITE_APP_BASE_API: string
  readonly VITE_APP_BASE_URL: string
  readonly VITE_APP_ENV: 'development' | 'production'
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

src/App.vue

vue

<template>
  <a-config-provider>
    <router-view />
  </a-config-provider>
</template>

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  name: 'App'
})
</script>

<style>
#app {
  height: 100vh;
}
</style>

src/router/index.ts

typescript

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import HomeView from '@/views/HomeView.vue'

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    component: () => import('@/views/AboutView.vue')
  }
]

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes
})

export default router

src/stores/index.ts (Pinia store)

typescript

import { defineStore } from 'pinia'

interface AppState {
  count: number
}

export const useAppStore = defineStore('app', {
  state: (): AppState => ({
    count: 0
  }),
  getters: {
    doubleCount: (state) => state.count * 2
  },
  actions: {
    increment() {
      this.count++
    },
    decrement() {
      this.count--
    }
  }
})

src/api/index.ts (Axios封装)

typescript

import axios from 'axios'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { message } from 'ant-design-vue'

const service: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 10000
})

// 请求拦截器
service.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    // 在这里可以添加token等
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    const res = response.data
    if (res.code !== 200) {
      message.error(res.message || 'Error')
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
  (error) => {
    message.error(error.message || 'Error')
    return Promise.reject(error)
  }
)

export default service

src/views/HomeView.vue

vue

<template>
  <a-layout>
    <a-layout-header>
      <h1>{{ title }}</h1>
    </a-layout-header>
    <a-layout-content>
      <div class="content">
        <a-button type="primary" @click="handleIncrement">Increment</a-button>
        <span class="count">Count: {{ count }}</span>
        <span class="double-count">Double Count: {{ doubleCount }}</span>
        <a-button @click="handleDecrement">Decrement</a-button>
      </div>
    </a-layout-content>
  </a-layout>
</template>

<script lang="ts">
import { defineComponent, computed } from 'vue'
import { useAppStore } from '@/stores'
import { message } from 'ant-design-vue'

export default defineComponent({
  name: 'HomeView',
  setup() {
    const store = useAppStore()
    const title = import.meta.env.VITE_APP_TITLE

    const count = computed(() => store.count)
    const doubleCount = computed(() => store.doubleCount)

    const handleIncrement = () => {
      store.increment()
      message.success('Incremented!')
    }

    const handleDecrement = () => {
      store.decrement()
      message.warning('Decremented!')
    }

    return {
      title,
      count,
      doubleCount,
      handleIncrement,
      handleDecrement
    }
  }
})
</script>

<style scoped>
.content {
  padding: 24px;
  text-align: center;
}

.count,
.double-count {
  display: inline-block;
  margin: 0 16px;
  font-size: 18px;
}
</style>

src/views/AboutView.vue

vue

<template>
  <div class="about">
    <h1>This is an about page</h1>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  name: 'AboutView'
})
</script>

6. .gitignore

text

.DS_Store
node_modules
/dist
.env.local
.env.*.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

使用说明

  1. 安装依赖:

bash

npm install
  1. 运行开发服务器:

bash

npm run dev
  1. 构建生产版本:

bash

npm run build
  1. 预览生产版本:

bash

npm run preview

这个脚手架包含了:

  • Vue 3 组合式API
  • Vite 构建工具
  • Ant Design Vue UI组件库
  • Pinia 状态管理
  • Axios HTTP客户端
  • TypeScript 支持
  • 环境变量配置
  • 路由配置
  • 基本的布局和组件

你可以根据需要进一步扩展这个基础结构。

额外建议

  1. 可以添加ESLint和Prettier进行代码规范
  2. 考虑添加Husky和lint-staged进行Git提交前检查
  3. 可以配置Mock.js进行接口模拟开发
  4. 考虑添加VueUse库提供更多实用的组合式API

希望这个脚手架对你的项目有所帮助!