Vue SPA Template
The Vue SPA template provides a modern Vue 3 development environment with TypeScript, Vite, Vue Router, and Pinia. It's perfect for building single-page applications with excellent developer experience.
Technical Stack
- Vue 3 - Progressive JavaScript framework
- TypeScript - Type-safe development
- Vite - Fast build tool and dev server
- Vue Router - Official routing library
- Pinia - State management library
- Vue i18n - Internationalization
- Tailwind CSS - Utility-first CSS framework
- SCSS - CSS preprocessor
Quick Start
1. Create Project
bash
# Initialize project
vup init my-vue-project
cd my-vue-project
# Add Vue template
vup add my-vue-app2. Install Dependencies
bash
# Install dependencies
pnpm install3. Start Development
bash
# Start development server
cd apps/my-vue-app
pnpm devThe application will be available at http://localhost:9301.
Project Structure
apps/my-vue-app/
├── src/
│ ├── assets/ # Static assets
│ │ └── images/ # Image files
│ ├── locales/ # Internationalization
│ │ ├── index.ts # i18n configuration
│ │ ├── en_US.ts # English translations
│ │ └── zh_CN.ts # Chinese translations
│ ├── api/ # API layer
│ │ ├── request.ts
│ │ └── types.ts
│ ├── modules/
│ │ └── demo/ # Demo module
│ │ ├── api/
│ │ │ └── task.ts
│ │ ├── components/
│ │ │ ├── DemoHero.vue
│ │ │ ├── DemoQuickStart.vue
│ │ │ ├── DemoStructureGuide.vue
│ │ │ └── DemoTaskBoard.vue
│ │ ├── locales/
│ │ │ ├── en_US.ts
│ │ │ └── zh_CN.ts
│ │ ├── stores/
│ │ │ └── useDemoTaskStore.ts
│ │ ├── types/
│ │ │ └── task.ts
│ │ └── views/
│ │ ├── DemoLayout.vue
│ │ ├── DemoGuidePage.vue
│ │ └── DemoExamplePage.vue
│ ├── router/ # Vue Router
│ │ ├── index.ts # Router configuration
│ │ └── routes.ts # Route definitions
│ ├── views/ # Page components
│ │ └── empty/
│ │ └── Empty.vue
│ ├── App.vue # Root component
│ ├── main.ts # Application entry point
│ └── vue-shim.d.ts # Vue type declarations
├── .env.example # Environment variables example
├── auto-imports.d.ts # Auto imports declarations
├── public/ # Public assets
│ ├── favicon.ico
├── index.html # HTML template
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
└── vite.config.js # Vite configurationCore Features
Vue 3 Composition API
vue
<template>
<div class="container">
<h1>{{ title }}</h1>
<p>{{ description }}</p>
<button @click="increment">Count: {{ count }}</button>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue';
const count = ref(0);
const title = ref('Vue 3 App');
const description = computed(() => `Current count is ${count.value}`);
const increment = () => {
count.value++;
};
</script>Vue Router
typescript
// router/routes.ts
import type { RouteRecordRaw } from 'vue-router';
export const routes: RouteRecordRaw[] = [
{
path: '/',
redirect: { name: 'demo-guide' },
},
{
path: '/demo',
component: () => import('@/modules/demo/views/DemoLayout.vue'),
children: [
{
path: '',
redirect: { name: 'demo-guide' },
},
{
path: 'guide',
name: 'demo-guide',
component: () => import('@/modules/demo/views/DemoGuidePage.vue'),
},
{
path: 'example',
name: 'demo-example',
component: () => import('@/modules/demo/views/DemoExamplePage.vue'),
},
],
},
{
path: '/empty',
name: 'empty',
component: () => import('@/views/empty/Empty.vue'),
},
{
path: '/:pathMatch(.*)*',
redirect: { name: 'empty' },
},
];Pinia State Management
typescript
// src/modules/demo/stores/useDemoTaskStore.ts
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', () => {
const count = ref(0);
const increment = () => {
count.value++;
};
const decrement = () => {
count.value--;
};
return {
count,
increment,
decrement,
};
});Internationalization
typescript
// locales/en_US.ts
export default {
common: {
title: 'Vue 3 Application',
description: 'A modern Vue 3 application',
},
navigation: {
home: 'Home',
demo: 'Demo',
},
};Tailwind CSS Styling
vue
<template>
<div class="min-h-screen bg-gray-100">
<header class="bg-white shadow-sm">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h1 class="text-3xl font-bold text-gray-900">
{{ $t('common.title') }}
</h1>
</div>
</header>
<main class="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
<div class="px-4 py-6 sm:px-0">
<div class="border-4 border-dashed border-gray-200 rounded-lg h-96">
<p class="text-center text-gray-500 mt-20">
{{ $t('common.description') }}
</p>
</div>
</div>
</main>
</div>
</template>Development Tools
Vite Configuration
javascript
// vite.config.js
import path from 'path';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import AutoImport from 'unplugin-auto-import/vite';
export default defineConfig({
plugins: [
vue(),
vueJsx(),
AutoImport({
imports: ['vue', 'vue-router', 'pinia', 'vue-i18n'],
dts: path.resolve(__dirname, 'auto-imports.d.ts'),
vueTemplate: true,
}),
],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@_shared': path.resolve(__dirname, '../../_shared'),
},
},
css: {
postcss: path.resolve(__dirname, '../../postcss.config.js'),
},
server: {
host: '0.0.0.0',
port: 9301,
open: false,
cors: true,
},
});TypeScript Configuration
json
// tsconfig.json
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./.output",
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@_shared/*": ["../../_shared/*"]
}
},
"include": [
"src/**/*",
"src/**/*.vue",
"src/*.vue",
"./auto-imports.d.ts",
"src/vue-shim.d.ts"
]
}Available Scripts
json
{
"scripts": {
"dev": "vite",
"build": "tsc --noEmit && vite build",
"lint": "eslint src/ --ext .vue,.ts,.js",
"lint:fix": "eslint src/ --ext .vue,.ts,.js --fix",
"format": "prettier --write \"src/**/*.{js,ts,vue,json,css,scss}\"",
"format:check": "prettier --check \"src/**/*.{js,ts,vue,json,css,scss}\""
}
}Related Examples
Capability-focused demos are maintained in the base repository examples/ directory:
examples/mockexamples/pwaexamples/qiankun
Deployment
Build for Production
bash
cd apps/my-vue-app
# Build the application
pnpm build
# The built files will be in the .output directoryDeploy to Vercel
See Vercel Deployment Guide for detailed deployment instructions.