Search K
Appearance
Appearance
📊 SEO元描述:2024年最新Vue3+TypeScript配置教程,详解项目搭建、类型定义、开发工具配置。包含完整配置方案,适合Vue.js开发者快速上手TypeScript开发。
核心关键词:Vue3 TypeScript配置2024、Vue TypeScript项目搭建、Vue3 TS开发环境、Vue TypeScript最佳实践
长尾关键词:Vue3 TypeScript怎么配置、Vue TypeScript项目搭建步骤、Vue3 TS开发环境搭建、Vue TypeScript配置文件详解
通过本节Vue3+TypeScript配置深度教程,你将系统性掌握:
为什么选择Vue3+TypeScript?Vue3原生支持TypeScript,提供了完整的类型定义和开发体验。TypeScript能够为Vue3项目带来更好的类型安全、IDE支持和代码维护性,特别是在大型项目中。Vue3+TypeScript是现代前端开发的最佳组合。
💡 配置建议:使用官方脚手架工具创建项目,逐步配置和优化开发环境
使用Vue CLI或Vite创建Vue3+TypeScript项目:
# 使用Vue CLI创建项目
npm install -g @vue/cli
vue create vue3-typescript-project
# 或使用Vite创建项目(推荐)
npm create vue@latest vue3-typescript-project
cd vue3-typescript-project
npm install
# 或使用Vite模板
npm create vite@latest vue3-typescript-project -- --template vue-ts// package.json - 项目依赖配置
{
"name": "vue3-typescript-project",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"preview": "vite preview",
"type-check": "vue-tsc --noEmit",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"format": "prettier --write src/",
"test": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest --coverage"
},
"dependencies": {
"vue": "^3.4.0",
"vue-router": "^4.2.5",
"pinia": "^2.1.7",
"axios": "^1.6.0"
},
"devDependencies": {
"@types/node": "^20.10.0",
"@typescript-eslint/eslint-plugin": "^6.14.0",
"@typescript-eslint/parser": "^6.14.0",
"@vitejs/plugin-vue": "^4.5.2",
"@vue/eslint-config-prettier": "^8.0.0",
"@vue/eslint-config-typescript": "^12.0.0",
"@vue/test-utils": "^2.4.3",
"@vue/tsconfig": "^0.5.1",
"eslint": "^8.56.0",
"eslint-plugin-vue": "^9.19.2",
"jsdom": "^23.0.1",
"prettier": "^3.1.1",
"typescript": "~5.3.0",
"vite": "^5.0.10",
"vitest": "^1.1.0",
"vue-tsc": "^1.8.25"
}
}// tsconfig.json - TypeScript配置文件
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": [
"env.d.ts",
"src/**/*",
"src/**/*.vue"
],
"exclude": [
"src/**/__tests__/*"
],
"compilerOptions": {
// 基础配置
"target": "ES2020",
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"useDefineForClassFields": true,
// 模块解析
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
// 类型检查
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
// 互操作性
"allowJs": true,
"checkJs": false,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
// 路径映射
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@/components/*": ["./src/components/*"],
"@/views/*": ["./src/views/*"],
"@/utils/*": ["./src/utils/*"],
"@/types/*": ["./src/types/*"],
"@/api/*": ["./src/api/*"],
"@/stores/*": ["./src/stores/*"],
"@/assets/*": ["./src/assets/*"]
},
// JSX配置
"jsx": "preserve",
"jsxImportSource": "vue",
// 实验性功能
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}// env.d.ts - 环境类型声明
/// <reference types="vite/client" />
// Vue单文件组件类型声明
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
// 环境变量类型声明
interface ImportMetaEnv {
readonly VITE_APP_TITLE: string
readonly VITE_APP_API_BASE_URL: string
readonly VITE_APP_VERSION: string
readonly VITE_APP_BUILD_TIME: string
readonly VITE_APP_ENVIRONMENT: 'development' | 'staging' | 'production'
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
// 全局类型声明
declare global {
// 窗口对象扩展
interface Window {
__VUE_DEVTOOLS_GLOBAL_HOOK__?: any
gtag?: (...args: any[]) => void
dataLayer?: any[]
}
// 自定义事件类型
interface CustomEventMap {
'user-login': CustomEvent<{ userId: string; username: string }>
'user-logout': CustomEvent<void>
'theme-change': CustomEvent<{ theme: 'light' | 'dark' }>
}
// 扩展EventTarget
interface EventTarget {
addEventListener<K extends keyof CustomEventMap>(
type: K,
listener: (this: EventTarget, ev: CustomEventMap[K]) => void,
options?: boolean | AddEventListenerOptions
): void
removeEventListener<K extends keyof CustomEventMap>(
type: K,
listener: (this: EventTarget, ev: CustomEventMap[K]) => void,
options?: boolean | EventListenerOptions
): void
}
}
// 模块声明
declare module 'virtual:*' {
const result: any
export default result
}
// 图片资源类型
declare module '*.png' {
const src: string
export default src
}
declare module '*.jpg' {
const src: string
export default src
}
declare module '*.jpeg' {
const src: string
export default src
}
declare module '*.gif' {
const src: string
export default src
}
declare module '*.svg' {
const src: string
export default src
}
declare module '*.webp' {
const src: string
export default src
}
// CSS模块类型
declare module '*.module.css' {
const classes: { readonly [key: string]: string }
export default classes
}
declare module '*.module.scss' {
const classes: { readonly [key: string]: string }
export default classes
}
declare module '*.module.sass' {
const classes: { readonly [key: string]: string }
export default classes
}
declare module '*.module.less' {
const classes: { readonly [key: string]: string }
export default classes
}
export {}// vite.config.ts - Vite配置文件
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
import type { UserConfig, ConfigEnv } from 'vite'
export default defineConfig(({ command, mode }: ConfigEnv): UserConfig => {
// 加载环境变量
const env = loadEnv(mode, process.cwd(), '')
return {
plugins: [
vue({
script: {
// 启用defineModel宏
defineModel: true,
// 启用propsDestructure
propsDestructure: true
}
})
],
// 路径解析
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
'@/components': resolve(__dirname, 'src/components'),
'@/views': resolve(__dirname, 'src/views'),
'@/utils': resolve(__dirname, 'src/utils'),
'@/types': resolve(__dirname, 'src/types'),
'@/api': resolve(__dirname, 'src/api'),
'@/stores': resolve(__dirname, 'src/stores'),
'@/assets': resolve(__dirname, 'src/assets')
}
},
// 开发服务器配置
server: {
host: '0.0.0.0',
port: 3000,
open: true,
cors: true,
proxy: {
'/api': {
target: env.VITE_APP_API_BASE_URL || 'http://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
// 构建配置
build: {
target: 'es2015',
outDir: 'dist',
assetsDir: 'assets',
sourcemap: mode === 'development',
minify: 'terser',
terserOptions: {
compress: {
drop_console: mode === 'production',
drop_debugger: mode === 'production'
}
},
rollupOptions: {
output: {
chunkFileNames: 'js/[name]-[hash].js',
entryFileNames: 'js/[name]-[hash].js',
assetFileNames: '[ext]/[name]-[hash].[ext]',
manualChunks: {
vue: ['vue', 'vue-router', 'pinia'],
vendor: ['axios', 'lodash-es']
}
}
}
},
// CSS配置
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/styles/variables.scss";`
}
},
modules: {
localsConvention: 'camelCase'
}
},
// 环境变量
define: {
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false,
__APP_VERSION__: JSON.stringify(process.env.npm_package_version),
__BUILD_TIME__: JSON.stringify(new Date().toISOString())
},
// 优化配置
optimizeDeps: {
include: ['vue', 'vue-router', 'pinia', 'axios'],
exclude: ['@vue/devtools-api']
},
// 测试配置
test: {
globals: true,
environment: 'jsdom',
setupFiles: ['./src/test/setup.ts']
}
}
})开发工具配置是提升Vue3+TypeScript开发效率的关键:
// .vscode/settings.json - VSCode工作区设置
{
// TypeScript配置
"typescript.preferences.quoteStyle": "single",
"typescript.preferences.includePackageJsonAutoImports": "auto",
"typescript.suggest.autoImports": true,
"typescript.updateImportsOnFileMove.enabled": "always",
"typescript.inlayHints.parameterNames.enabled": "literals",
"typescript.inlayHints.variableTypes.enabled": true,
"typescript.inlayHints.functionLikeReturnTypes.enabled": true,
// Vue配置
"vue.codeActions.enabled": true,
"vue.complete.casing.tags": "kebab",
"vue.complete.casing.props": "camel",
"vue.inlayHints.missingProps": true,
"vue.inlayHints.inlineHandlerLeading": true,
"vue.inlayHints.optionsWrapper": true,
// 编辑器配置
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.organizeImports": true
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.detectIndentation": false,
// 文件关联
"files.associations": {
"*.vue": "vue"
},
// 搜索配置
"search.exclude": {
"**/node_modules": true,
"**/dist": true,
"**/.git": true,
"**/.DS_Store": true,
"**/coverage": true
},
// 文件监听
"files.watcherExclude": {
"**/node_modules/**": true,
"**/dist/**": true,
"**/.git/**": true
},
// Emmet配置
"emmet.includeLanguages": {
"vue-html": "html",
"vue": "html"
},
// 自动保存
"files.autoSave": "onFocusChange",
// 终端配置
"terminal.integrated.defaultProfile.windows": "PowerShell",
"terminal.integrated.fontSize": 14
}// .vscode/extensions.json - 推荐插件
{
"recommendations": [
// Vue开发必备
"Vue.volar",
"Vue.vscode-typescript-vue-plugin",
// TypeScript支持
"ms-vscode.vscode-typescript-next",
// 代码格式化
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
// 开发工具
"bradlc.vscode-tailwindcss",
"formulahendry.auto-rename-tag",
"christian-kohler.path-intellisense",
"ms-vscode.vscode-json",
// Git工具
"eamodio.gitlens",
"mhutchie.git-graph",
// 主题和图标
"PKief.material-icon-theme",
"GitHub.github-vscode-theme",
// 实用工具
"streetsidesoftware.code-spell-checker",
"wayou.vscode-todo-highlight",
"aaron-bond.better-comments",
"ms-vscode.live-server"
]
}// .eslintrc.json - ESLint配置
{
"root": true,
"env": {
"node": true,
"browser": true,
"es2022": true
},
"extends": [
"eslint:recommended",
"@vue/eslint-config-typescript",
"@vue/eslint-config-prettier",
"plugin:vue/vue3-recommended"
],
"parser": "vue-eslint-parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module",
"parser": "@typescript-eslint/parser"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
// Vue规则
"vue/multi-word-component-names": "off",
"vue/no-unused-vars": "error",
"vue/no-mutating-props": "error",
"vue/no-v-html": "warn",
"vue/require-default-prop": "error",
"vue/require-prop-types": "error",
"vue/component-name-in-template-casing": ["error", "kebab-case"],
"vue/custom-event-name-casing": ["error", "kebab-case"],
// TypeScript规则
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-non-null-assertion": "warn",
"@typescript-eslint/prefer-const": "error",
"@typescript-eslint/no-var-requires": "error",
// 通用规则
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-unused-vars": "off",
"prefer-const": "error",
"no-var": "error",
"object-shorthand": "error",
"prefer-template": "error"
},
"overrides": [
{
"files": ["**/__tests__/*.{j,t}s?(x)", "**/tests/unit/**/*.spec.{j,t}s?(x)"],
"env": {
"jest": true
}
}
]
}// .prettierrc.json - Prettier配置
{
"semi": false,
"singleQuote": true,
"quoteProps": "as-needed",
"trailingComma": "es5",
"tabWidth": 2,
"useTabs": false,
"printWidth": 100,
"bracketSpacing": true,
"bracketSameLine": false,
"arrowParens": "avoid",
"endOfLine": "lf",
"vueIndentScriptAndStyle": false,
"singleAttributePerLine": false,
"htmlWhitespaceSensitivity": "css"
}开发工具配置核心要点:
💼 工具提示:配置好开发工具能显著提升开发效率,建议团队统一开发环境配置
建立清晰的类型定义结构和管理策略:
// src/types/index.ts - 全局类型导出
// 基础类型
export * from './base'
export * from './api'
export * from './user'
export * from './common'
// 组件类型
export * from './components'
// 路由类型
export * from './router'
// 状态管理类型
export * from './store'
// 工具类型
export * from './utils'// src/types/base.ts - 基础类型定义
// 基础数据类型
export type ID = string | number
export type Timestamp = number | string | Date
export type Status = 'pending' | 'loading' | 'success' | 'error'
export type Theme = 'light' | 'dark' | 'auto'
export type Language = 'zh-CN' | 'en-US' | 'ja-JP'
// 分页类型
export interface Pagination {
page: number
pageSize: number
total: number
}
export interface PaginationParams {
page?: number
pageSize?: number
}
export interface PaginatedResponse<T> {
data: T[]
pagination: Pagination
}
// 排序类型
export type SortOrder = 'asc' | 'desc'
export interface SortConfig {
field: string
order: SortOrder
}
// 筛选类型
export interface FilterConfig {
field: string
operator: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'in'
value: any
}
// 表格列配置
export interface TableColumn<T = any> {
key: keyof T
title: string
width?: number
sortable?: boolean
filterable?: boolean
render?: (value: any, record: T, index: number) => any
}
// 表单字段类型
export interface FormField {
name: string
label: string
type: 'text' | 'email' | 'password' | 'number' | 'select' | 'checkbox' | 'radio' | 'textarea'
required?: boolean
placeholder?: string
options?: Array<{ label: string; value: any }>
validation?: {
min?: number
max?: number
pattern?: RegExp
message?: string
}
}
// 菜单类型
export interface MenuItem {
id: ID
title: string
icon?: string
path?: string
children?: MenuItem[]
meta?: {
requiresAuth?: boolean
roles?: string[]
hidden?: boolean
}
}
// 面包屑类型
export interface BreadcrumbItem {
title: string
path?: string
icon?: string
}
// 通知类型
export interface Notification {
id: ID
type: 'info' | 'success' | 'warning' | 'error'
title: string
message: string
duration?: number
timestamp: Timestamp
}
// 文件类型
export interface FileInfo {
id: ID
name: string
size: number
type: string
url: string
uploadTime: Timestamp
}
// 地址类型
export interface Address {
province: string
city: string
district: string
street: string
zipCode?: string
}
// 联系信息类型
export interface ContactInfo {
phone?: string
email?: string
address?: Address
}// src/types/api.ts - API相关类型
// 基础API响应类型
export interface ApiResponse<T = any> {
code: number
message: string
data: T
success: boolean
timestamp: Timestamp
}
// API错误类型
export interface ApiError {
code: number
message: string
details?: any
timestamp: Timestamp
}
// 请求配置类型
export interface RequestConfig {
url: string
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'
params?: Record<string, any>
data?: any
headers?: Record<string, string>
timeout?: number
retry?: number
}
// 上传配置类型
export interface UploadConfig {
url: string
field: string
accept?: string
maxSize?: number
multiple?: boolean
headers?: Record<string, string>
}
// 下载配置类型
export interface DownloadConfig {
url: string
filename?: string
headers?: Record<string, string>
}
// API端点类型
export interface ApiEndpoints {
// 用户相关
user: {
login: string
logout: string
profile: string
register: string
resetPassword: string
}
// 文件相关
file: {
upload: string
download: string
delete: string
}
// 其他端点...
}
// HTTP状态码类型
export type HttpStatusCode =
| 200 // OK
| 201 // Created
| 204 // No Content
| 400 // Bad Request
| 401 // Unauthorized
| 403 // Forbidden
| 404 // Not Found
| 422 // Unprocessable Entity
| 500 // Internal Server Error
| 502 // Bad Gateway
| 503 // Service Unavailable
// 请求状态类型
export interface RequestState {
loading: boolean
error: ApiError | null
data: any
}
// 缓存配置类型
export interface CacheConfig {
key: string
ttl: number // 生存时间(毫秒)
storage: 'memory' | 'localStorage' | 'sessionStorage'
}// src/types/user.ts - 用户相关类型
// 用户基础信息
export interface User {
id: ID
username: string
email: string
phone?: string
avatar?: string
nickname?: string
gender?: 'male' | 'female' | 'other'
birthday?: string
bio?: string
status: 'active' | 'inactive' | 'banned'
createdAt: Timestamp
updatedAt: Timestamp
}
// 用户角色
export interface Role {
id: ID
name: string
code: string
description?: string
permissions: Permission[]
}
// 权限
export interface Permission {
id: ID
name: string
code: string
resource: string
action: string
description?: string
}
// 用户登录信息
export interface LoginCredentials {
username: string
password: string
captcha?: string
rememberMe?: boolean
}
// 用户注册信息
export interface RegisterData {
username: string
email: string
password: string
confirmPassword: string
phone?: string
captcha: string
agreement: boolean
}
// 用户资料更新
export interface UserProfileUpdate {
nickname?: string
avatar?: string
gender?: 'male' | 'female' | 'other'
birthday?: string
bio?: string
phone?: string
}
// 密码修改
export interface PasswordChange {
oldPassword: string
newPassword: string
confirmPassword: string
}
// 用户会话信息
export interface UserSession {
token: string
refreshToken?: string
expiresAt: Timestamp
user: User
permissions: string[]
roles: string[]
}
// 用户偏好设置
export interface UserPreferences {
theme: Theme
language: Language
timezone: string
notifications: {
email: boolean
push: boolean
sms: boolean
}
privacy: {
profileVisible: boolean
emailVisible: boolean
phoneVisible: boolean
}
}
// 用户统计信息
export interface UserStats {
loginCount: number
lastLoginAt: Timestamp
lastLoginIp: string
totalOnlineTime: number
createdContentCount: number
}// src/types/components.ts - 组件相关类型
import type { Component, VNode } from 'vue'
// 按钮组件类型
export interface ButtonProps {
type?: 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info'
size?: 'small' | 'medium' | 'large'
disabled?: boolean
loading?: boolean
icon?: string
round?: boolean
circle?: boolean
plain?: boolean
ghost?: boolean
}
// 输入框组件类型
export interface InputProps {
modelValue?: string | number
type?: 'text' | 'password' | 'email' | 'number' | 'tel' | 'url'
placeholder?: string
disabled?: boolean
readonly?: boolean
clearable?: boolean
showPassword?: boolean
maxlength?: number
minlength?: number
size?: 'small' | 'medium' | 'large'
prefix?: string
suffix?: string
}
// 表格组件类型
export interface TableProps<T = any> {
data: T[]
columns: TableColumn<T>[]
loading?: boolean
pagination?: Pagination
selection?: boolean
sortable?: boolean
filterable?: boolean
bordered?: boolean
striped?: boolean
size?: 'small' | 'medium' | 'large'
}
// 对话框组件类型
export interface DialogProps {
modelValue: boolean
title?: string
width?: string | number
height?: string | number
modal?: boolean
closeOnClickModal?: boolean
closeOnPressEscape?: boolean
showClose?: boolean
beforeClose?: (done: () => void) => void
}
// 表单组件类型
export interface FormProps {
model: Record<string, any>
rules?: Record<string, any>
labelWidth?: string | number
labelPosition?: 'left' | 'right' | 'top'
inline?: boolean
disabled?: boolean
size?: 'small' | 'medium' | 'large'
}
// 菜单组件类型
export interface MenuProps {
items: MenuItem[]
mode?: 'horizontal' | 'vertical'
collapsed?: boolean
defaultActive?: string
router?: boolean
uniqueOpened?: boolean
}
// 分页组件类型
export interface PaginationProps {
currentPage: number
pageSize: number
total: number
pageSizes?: number[]
layout?: string
background?: boolean
small?: boolean
}
// 上传组件类型
export interface UploadProps {
action: string
accept?: string
multiple?: boolean
limit?: number
fileList?: FileInfo[]
autoUpload?: boolean
showFileList?: boolean
drag?: boolean
beforeUpload?: (file: File) => boolean | Promise<boolean>
onSuccess?: (response: any, file: File, fileList: FileInfo[]) => void
onError?: (error: any, file: File, fileList: FileInfo[]) => void
}
// 图片预览组件类型
export interface ImagePreviewProps {
src: string
alt?: string
width?: string | number
height?: string | number
fit?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down'
lazy?: boolean
previewSrcList?: string[]
zIndex?: number
}
// 加载组件类型
export interface LoadingProps {
loading: boolean
text?: string
spinner?: string | Component
background?: string
customClass?: string
}
// 空状态组件类型
export interface EmptyProps {
image?: string | Component
imageSize?: number
description?: string | VNode
}
// 骨架屏组件类型
export interface SkeletonProps {
loading: boolean
animated?: boolean
count?: number
rows?: number
rowsWidth?: string | number | Array<string | number>
title?: boolean
titleWidth?: string | number
avatar?: boolean
avatarSize?: 'small' | 'medium' | 'large'
avatarShape?: 'circle' | 'square'
}// src/types/vendor.ts - 第三方库类型扩展
// Axios扩展类型
declare module 'axios' {
export interface AxiosRequestConfig {
retry?: number
retryDelay?: number
cache?: boolean
cacheTime?: number
loading?: boolean
errorMessage?: boolean
}
}
// Vue Router扩展类型
declare module 'vue-router' {
interface RouteMeta {
title?: string
icon?: string
requiresAuth?: boolean
roles?: string[]
permissions?: string[]
hidden?: boolean
keepAlive?: boolean
affix?: boolean
breadcrumb?: boolean
activeMenu?: string
}
}
// Pinia扩展类型
declare module 'pinia' {
export interface DefineStoreOptionsBase<S, Store> {
persist?: boolean | {
key?: string
storage?: Storage
paths?: string[]
}
}
}
// Element Plus扩展类型
declare module '@element-plus/icons-vue' {
import type { Component } from 'vue'
const icons: Record<string, Component>
export default icons
}
// Lodash扩展类型
declare module 'lodash-es' {
interface LoDashStatic {
customMethod: (value: any) => any
}
}
// Chart.js类型
export interface ChartConfig {
type: 'line' | 'bar' | 'pie' | 'doughnut' | 'radar' | 'scatter'
data: {
labels: string[]
datasets: Array<{
label: string
data: number[]
backgroundColor?: string | string[]
borderColor?: string | string[]
borderWidth?: number
}>
}
options?: {
responsive?: boolean
maintainAspectRatio?: boolean
plugins?: {
legend?: {
display?: boolean
position?: 'top' | 'bottom' | 'left' | 'right'
}
title?: {
display?: boolean
text?: string
}
}
scales?: {
x?: {
display?: boolean
title?: {
display?: boolean
text?: string
}
}
y?: {
display?: boolean
title?: {
display?: boolean
text?: string
}
}
}
}
}
// 日期库类型
export interface DateConfig {
format: string
locale: string
timezone: string
}
// 国际化类型
export interface I18nConfig {
locale: string
fallbackLocale: string
messages: Record<string, Record<string, string>>
}
// 主题配置类型
export interface ThemeConfig {
name: string
colors: {
primary: string
secondary: string
success: string
warning: string
danger: string
info: string
light: string
dark: string
}
fonts: {
family: string
size: {
small: string
medium: string
large: string
}
}
spacing: {
small: string
medium: string
large: string
}
borderRadius: {
small: string
medium: string
large: string
}
shadows: {
small: string
medium: string
large: string
}
}通过本节Vue3+TypeScript配置深度教程的学习,你已经掌握:
A: 推荐使用Vite,它提供更快的开发服务器、更好的TypeScript支持和现代化的构建体验。Webpack适合需要复杂配置的大型项目。
A: 初期可能会增加一些工作量,但长期来看能显著提升代码质量和维护性。建议渐进式启用严格模式选项。
A: 查找@types包、编写.d.ts声明文件或使用模块声明。也可以暂时使用any类型,后续再完善类型定义。
A: 使用@vue/eslint-config-prettier禁用ESLint中与Prettier冲突的规则,让Prettier专门处理代码格式化。
A: 启用增量编译、配置合适的include/exclude、使用项目引用、合理设置skipLibCheck等选项。
// scripts/build.ts - 构建脚本
import { build } from 'vite'
import { resolve } from 'path'
async function buildProject() {
try {
console.log('🚀 Starting production build...')
await build({
root: resolve(__dirname, '..'),
build: {
outDir: 'dist',
emptyOutDir: true,
sourcemap: false,
minify: 'terser',
target: 'es2015',
rollupOptions: {
output: {
manualChunks: {
vue: ['vue', 'vue-router', 'pinia'],
vendor: ['axios', 'lodash-es'],
ui: ['element-plus']
}
}
}
}
})
console.log('✅ Build completed successfully!')
} catch (error) {
console.error('❌ Build failed:', error)
process.exit(1)
}
}
buildProject()"Vue3+TypeScript配置是现代前端开发的重要基础。通过合理的项目配置、开发工具集成和类型管理,我们能够构建高质量、可维护的Vue应用。良好的配置是项目成功的第一步,为后续开发奠定坚实基础!"