2026-06-18 16:47:36 +08:00
|
|
|
# Vue SPA Template
|
2026-06-18 16:36:31 +08:00
|
|
|
|
2026-06-18 16:47:36 +08:00
|
|
|
A production-ready Vue 3 single-page application template with TypeScript, Pinia, Vue Router, and Tailwind CSS v4.
|
2026-06-18 16:36:31 +08:00
|
|
|
|
2026-06-18 16:47:36 +08:00
|
|
|
## Features
|
2026-06-18 16:36:31 +08:00
|
|
|
|
2026-06-18 16:47:36 +08:00
|
|
|
- **Vue 3** with Composition API and `<script setup>` syntax
|
|
|
|
|
- **TypeScript** — strict mode, path aliases, project references
|
|
|
|
|
- **Vue Router 5** — nested routes, layout system, navigation guards
|
|
|
|
|
- **Pinia 3** — state management with example stores
|
|
|
|
|
- **Tailwind CSS v4** — utility-first CSS with `@theme` custom tokens
|
|
|
|
|
- **Dark mode** — system-aware with manual toggle, persisted to `localStorage`
|
|
|
|
|
- **Authentication** — mock login flow with route guards and token management
|
|
|
|
|
- **Axios** — pre-configured HTTP client with auth interceptor
|
|
|
|
|
- **dayjs** — date utility with duration plugin
|
|
|
|
|
- **Vitest** — unit testing with jsdom and Vue Test Utils
|
|
|
|
|
- **Prettier** + **ESLint** + **oxlint** — consistent code quality
|
2026-06-18 16:36:31 +08:00
|
|
|
|
2026-06-18 16:47:36 +08:00
|
|
|
## Project Structure
|
2026-06-18 16:36:31 +08:00
|
|
|
|
2026-06-18 16:47:36 +08:00
|
|
|
```
|
|
|
|
|
src/
|
|
|
|
|
assets/ # Static assets and global CSS
|
|
|
|
|
components/ # Reusable Vue components
|
|
|
|
|
layouts/ # Page layout components
|
|
|
|
|
router/ # Vue Router configuration and guards
|
|
|
|
|
stores/ # Pinia stores
|
|
|
|
|
utils/ # Utility modules (axios, dayjs)
|
|
|
|
|
views/ # Page-level components
|
|
|
|
|
```
|
2026-06-18 16:36:31 +08:00
|
|
|
|
2026-06-18 16:47:36 +08:00
|
|
|
## Getting Started
|
2026-06-18 16:36:31 +08:00
|
|
|
|
2026-06-18 16:47:36 +08:00
|
|
|
### Prerequisites
|
2026-06-18 16:36:31 +08:00
|
|
|
|
2026-06-18 16:47:36 +08:00
|
|
|
- [Node.js](https://nodejs.org/) 20.19+ or 22.12+
|
|
|
|
|
- [pnpm](https://pnpm.io/) 9+
|
2026-06-18 16:36:31 +08:00
|
|
|
|
2026-06-18 16:47:36 +08:00
|
|
|
### Setup
|
2026-06-18 16:36:31 +08:00
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
pnpm install
|
|
|
|
|
```
|
|
|
|
|
|
2026-06-18 16:47:36 +08:00
|
|
|
Copy the environment file and adjust as needed:
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
cp .env.example .env
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Development
|
2026-06-18 16:36:31 +08:00
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
pnpm dev
|
|
|
|
|
```
|
|
|
|
|
|
2026-06-18 16:47:36 +08:00
|
|
|
### Build
|
2026-06-18 16:36:31 +08:00
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
pnpm build
|
|
|
|
|
```
|
|
|
|
|
|
2026-06-18 16:47:36 +08:00
|
|
|
### Preview Production Build
|
2026-06-18 16:36:31 +08:00
|
|
|
|
|
|
|
|
```sh
|
2026-06-18 16:47:36 +08:00
|
|
|
pnpm preview
|
2026-06-18 16:36:31 +08:00
|
|
|
```
|
2026-06-18 16:47:36 +08:00
|
|
|
|
|
|
|
|
## Scripts
|
|
|
|
|
|
|
|
|
|
| Command | Description |
|
|
|
|
|
| -------------------- | ---------------------------------------- |
|
|
|
|
|
| `pnpm dev` | Start development server with hot reload |
|
|
|
|
|
| `pnpm build` | Type-check and build for production |
|
|
|
|
|
| `pnpm preview` | Preview the production build locally |
|
|
|
|
|
| `pnpm lint` | Run oxlint and ESLint |
|
|
|
|
|
| `pnpm format` | Format source files with Prettier |
|
|
|
|
|
| `pnpm test:unit` | Run unit tests in watch mode |
|
|
|
|
|
| `pnpm test:unit:run` | Run unit tests once |
|
|
|
|
|
| `pnpm type-check` | Run TypeScript type checking |
|
|
|
|
|
|
|
|
|
|
## Authentication
|
|
|
|
|
|
|
|
|
|
The template includes a mock authentication flow for demonstration:
|
|
|
|
|
|
|
|
|
|
- The auth store manages a mock JWT token in `localStorage`
|
|
|
|
|
- Protected routes use `meta.requiresAuth` — unauthenticated users are redirected to `/login`
|
|
|
|
|
- Guest-only routes use `meta.guestOnly` — authenticated users are redirected to home
|
|
|
|
|
- The axios client automatically attaches the token and redirects on 401
|
|
|
|
|
|
|
|
|
|
Replace the `login()` function in `src/stores/auth.ts` with a real API call for production use.
|
|
|
|
|
|
|
|
|
|
## Theming
|
|
|
|
|
|
|
|
|
|
Dark mode uses Tailwind CSS v4's `@custom-variant dark` with CSS custom properties:
|
|
|
|
|
|
|
|
|
|
- Colour tokens are defined in `src/assets/main.css` under `:root` and `.dark`
|
|
|
|
|
- Components use semantic utilities like `bg-surface`, `text-foreground`, `border-border`
|
|
|
|
|
- The `useTheme()` composable toggles the `dark` class on `<html>` and persists to `localStorage`
|
|
|
|
|
- System preference is respected until the user makes an explicit choice
|
|
|
|
|
|
|
|
|
|
## Environment Variables
|
|
|
|
|
|
|
|
|
|
See `.env.example` for available variables.
|
|
|
|
|
|
|
|
|
|
| Variable | Default | Description |
|
|
|
|
|
| -------------------- | ------------------- | -------------------------- |
|
|
|
|
|
| `VITE_API_BASE_URL` | `/api` | Base URL for axios requests |
|
|
|
|
|
| `VITE_APP_TITLE` | `Vue SPA Template` | Document title |
|
|
|
|
|
|
|
|
|
|
## Licence
|
|
|
|
|
|
|
|
|
|
[MIT](LICENCE)
|