├── .eslintrc.cjs ├── .github └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── .npmrc ├── .prettierrc.json ├── .vscode └── extensions.json ├── README-EN.md ├── README.md ├── commitlint.config.js ├── env.d.ts ├── index.html ├── package-lock.json ├── package.json ├── public └── favicon.ico ├── renovate.json ├── src ├── App.vue ├── api │ └── index.ts ├── assets │ ├── add.svg │ ├── main.css │ ├── user.svg │ ├── 管理者(2).svg │ └── 管理者.svg ├── components │ ├── AccountArticle.vue │ ├── AccountDetail.vue │ ├── Article.vue │ ├── Card.vue │ ├── MessageDropdown.vue │ ├── SideBar.vue │ ├── Statistic.vue │ ├── Table.vue │ ├── TableDetail.vue │ ├── Tabs.vue │ └── TodoList.vue ├── main.ts ├── router │ └── index.ts ├── stores │ ├── counter.ts │ ├── tabs.ts │ └── todos.ts └── views │ ├── AccountCenter.vue │ ├── Articles.vue │ ├── BasicForm.vue │ ├── ComplexTable.vue │ ├── Dashboard.vue │ ├── Home.vue │ ├── Login.vue │ ├── NotFound.vue │ ├── StepForm.vue │ ├── Table.vue │ └── User.vue ├── tsconfig.config.json ├── tsconfig.json ├── vercel.json └── vite.config.ts /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | require('@rushstack/eslint-patch/modern-module-resolution'); 3 | 4 | module.exports = { 5 | root: true, 6 | extends: [ 7 | 'plugin:vue/vue3-essential', 8 | 'eslint:recommended', 9 | '@vue/eslint-config-typescript', 10 | '@vue/eslint-config-prettier', 11 | ], 12 | parserOptions: { 13 | ecmaVersion: 'latest', 14 | }, 15 | rules: { 16 | 'vue/multi-word-component-names': 0, 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### 描述 4 | 5 | 6 | 7 | --- 8 | 9 | ### 选择 PR 分类 10 | 11 | - [ ] Bug 修复 12 | - [ ] 新功能 13 | - [ ] 代码优化 14 | - [ ] 其它 15 | 16 | ### 还需确认一下 17 | 18 | - [ ] 代码提交没有冲突并且已经通过格式化校验规则 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx --no -- commitlint --edit 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmmirror.com 2 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] 3 | } 4 | -------------------------------------------------------------------------------- /README-EN.md: -------------------------------------------------------------------------------- 1 | # vue3-management-system 2 | 3 | Language: English | [中文简体](README.md) 4 | 5 | Based on the background management system developed by Vue3 Family Bucket, [online address is here](https://vue3-management-system.vercel.app/login). It is suitable for students who are self-studying Vue3, and for quick delivery of outsourced projects. 6 | 7 | ## technology stack 8 | 9 | The project uses the technology stack as follows: 10 | 11 | - [x] Vue 3: Front-end framework 12 | - [x] TypeScript: Language 13 | - [x] Vite: packaging tool 14 | - [x] Pinia: state management 15 | - [x] Vue Router: route management 16 | - [x] Element Plus: UI component library 17 | - [x] Echarts: Charts 18 | - [x] Axios: network requests 19 | 20 | ## project screenshot 21 | 22 | Login page: 23 | ![image](https://user-images.githubusercontent.com/51811652/227832497-7bc46908-d818-48ce-8ecd-bac57c3d9855.png) 24 | 25 | home page: 26 | ![image](https://user-images.githubusercontent.com/51811652/227833231-3b91552a-618f-41de-bbc1-fc6f68177a7d.png) 27 | 28 | table page: 29 | ![image](https://user-images.githubusercontent.com/51811652/227835053-4d680143-b165-4bbf-9f04-97c4a5422635.png) 30 | 31 | ## Project Setup 32 | 33 | ``` 34 | # clone project 35 | git clone https://github.com/HearLing/vue3-management-system.git 36 | 37 | # enter the project directory 38 | cd vue3-management-system 39 | 40 | # install dependencies 41 | npm install 42 | 43 | # Local development, start the service 44 | npm run dev 45 | 46 | # package build 47 | npm run build 48 | 49 | # ESLint fixes 50 | npm run lint 51 | ``` 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue3-management-system 2 | 3 | 文档语言: [English](README-EN.md) | 中文简体 4 | 5 | 基于 Vue3 全家桶开发的后台管理系统,[线上地址在这](https://vue3-management-system.vercel.app/login)。适用于自学 Vue3 的同学,以及外包项目快速交付。 6 | 7 | ## 技术栈 8 | 9 | 该项目使用技术栈如下: 10 | 11 | - [x] Vue 3:前端框架 12 | - [x] TypeScript:语言 13 | - [x] Vite:打包工具 14 | - [x] Pinia:状态管理 15 | - [x] Vue Router:路由管理 16 | - [x] Element Plus:UI 组件库 17 | - [x] Echarts:图表 18 | - [x] Axios:网络请求 19 | 20 | ## 项目截图 21 | 22 | 登录页: 23 | ![image](https://user-images.githubusercontent.com/51811652/227832497-7bc46908-d818-48ce-8ecd-bac57c3d9855.png) 24 | 25 | 首页: 26 | ![image](https://user-images.githubusercontent.com/51811652/227833231-3b91552a-618f-41de-bbc1-fc6f68177a7d.png) 27 | 28 | 表格: 29 | ![image](https://user-images.githubusercontent.com/51811652/227835053-4d680143-b165-4bbf-9f04-97c4a5422635.png) 30 | 31 | ## 安装 32 | 33 | ``` 34 | # 克隆项目 35 | git clone https://github.com/HearLing/vue3-management-system.git 36 | 37 | # 进入项目目录 38 | cd vue3-management-system 39 | 40 | # 安装依赖 41 | npm install 42 | 43 | # 本地开发,启动服务 44 | npm run dev 45 | 46 | # 打包构建 47 | npm run build 48 | 49 | # ESLint修复 50 | npm run lint 51 | ``` 52 | 53 | ## 参考资料 54 | 55 | - [x] [参考项目](https://preview.pro.ant.design/dashboard/analysis) 56 | - [x] [Vue3 中文文档](https://cn.vuejs.org) 57 | - [x] [Vue Router 中文文档](https://router.vuejs.org/zh/) 58 | - [x] [Pinia 中文文档](https://pinia.vuejs.org/zh/) 59 | - [x] [Element Plus 中文文档](https://element-plus.gitee.io/zh-CN/guide/quickstart.html) 60 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | module.exports = { 3 | extends: ['@commitlint/config-conventional'], 4 | }; 5 | -------------------------------------------------------------------------------- /env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue3-management-system", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "run-p type-check build-only", 8 | "preview": "vite preview", 9 | "build-only": "vite build", 10 | "type-check": "vue-tsc --noEmit", 11 | "lint": "npm run lint:staged -- .", 12 | "lint:staged": "eslint --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", 13 | "prepare": "husky install" 14 | }, 15 | "dependencies": { 16 | "@vueuse/core": "^9.13.0", 17 | "axios": "^1.3.3", 18 | "echarts": "^5.4.1", 19 | "element-plus": "^2.2.30", 20 | "pinia": "^2.0.28", 21 | "vue": "^3.2.45", 22 | "vue-router": "^4.1.6", 23 | "vxe-table": "^4.3.10", 24 | "xe-utils": "^3.5.7" 25 | }, 26 | "devDependencies": { 27 | "@commitlint/cli": "^17.4.4", 28 | "@commitlint/config-conventional": "^17.4.4", 29 | "@rushstack/eslint-patch": "^1.1.4", 30 | "@types/node": "^18.11.12", 31 | "@vitejs/plugin-vue": "^4.0.0", 32 | "@vitejs/plugin-vue-jsx": "^3.0.0", 33 | "@vue/eslint-config-prettier": "^7.0.0", 34 | "@vue/eslint-config-typescript": "^11.0.0", 35 | "@vue/tsconfig": "^0.1.3", 36 | "eslint": "^8.22.0", 37 | "eslint-plugin-vue": "^9.3.0", 38 | "husky": "^8.0.3", 39 | "lint-staged": "^13.1.2", 40 | "npm-run-all": "^4.1.5", 41 | "prettier": "^2.7.1", 42 | "sass": "^1.58.1", 43 | "scss": "^0.2.4", 44 | "typescript": "~4.7.4", 45 | "vite": "^4.0.0", 46 | "vue-tsc": "^1.0.12" 47 | }, 48 | "lint-staged": { 49 | "*.{js,ts,vue}": "npm run lint:staged --" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chovue/vue3-management-system/39694eddee2126e41d4dc8fb4d6a845918504344/public/favicon.ico -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/api/index.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import type { 3 | AxiosInstance, 4 | AxiosError, 5 | AxiosResponse, 6 | InternalAxiosRequestConfig, 7 | } from 'axios'; 8 | // 数据返回的接口 9 | // 定义请求响应参数,不含data 10 | interface Result { 11 | code: number; 12 | msg: string; 13 | } 14 | 15 | // 请求响应参数,包含data 16 | interface ResultData extends Result { 17 | data?: T; 18 | } 19 | 20 | const MOCKURL = 'https://mock.apifox.cn/m1/2328533-0-default'; 21 | 22 | const service: AxiosInstance = axios.create({ 23 | baseURL: MOCKURL, 24 | headers: { apifoxToken: sessionStorage.getItem('token') }, 25 | }); 26 | 27 | /** 28 | * 请求拦截器 29 | */ 30 | service.interceptors.request.use( 31 | (config: InternalAxiosRequestConfig) => { 32 | return config; 33 | }, 34 | (error: AxiosError) => { 35 | console.log(error); 36 | return Promise.reject(); 37 | } 38 | ); 39 | /** 40 | * 响应拦截器 41 | */ 42 | service.interceptors.response.use( 43 | (response: AxiosResponse | any) => { 44 | response; 45 | if (response.status === 200) { 46 | return response; 47 | } else { 48 | Promise.reject(); 49 | } 50 | }, 51 | (error: AxiosError) => { 52 | console.log(error); 53 | return Promise.reject(); 54 | } 55 | ); 56 | 57 | // 常用方法封装 58 | export function get(url: string, params?: object): Promise> { 59 | return service.get(url, { params }); 60 | } 61 | export function post(url: string, params?: object): Promise> { 62 | return service.post(url, params); 63 | } 64 | export function put(url: string, params?: object): Promise> { 65 | return service.put(url, params); 66 | } 67 | export function del(url: string, params?: object): Promise> { 68 | return service.delete(url, { params }); 69 | } 70 | -------------------------------------------------------------------------------- /src/assets/add.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | html, 7 | body, 8 | #app, 9 | .wrapper { 10 | width: 100%; 11 | height: 100%; 12 | overflow: hidden; 13 | } 14 | 15 | body { 16 | font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", 17 | "Microsoft YaHei", "微软雅黑", Arial, sans-serif; 18 | } 19 | 20 | a { 21 | text-decoration: none; 22 | } 23 | 24 | .fillcontain { 25 | height: 100%; 26 | width: 100%; 27 | } 28 | -------------------------------------------------------------------------------- /src/assets/user.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/管理者.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/AccountArticle.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /src/components/AccountDetail.vue: -------------------------------------------------------------------------------- 1 | 54 | 55 | 121 | 122 | 227 | -------------------------------------------------------------------------------- /src/components/Article.vue: -------------------------------------------------------------------------------- 1 | 2 | 45 | 46 | 62 | 152 | -------------------------------------------------------------------------------- /src/components/Card.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 28 | 29 | 165 | -------------------------------------------------------------------------------- /src/components/MessageDropdown.vue: -------------------------------------------------------------------------------- 1 | 93 | 94 | 177 | 178 | 303 | -------------------------------------------------------------------------------- /src/components/SideBar.vue: -------------------------------------------------------------------------------- 1 | 86 | 87 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /src/components/Statistic.vue: -------------------------------------------------------------------------------- 1 | 2 | 65 | 66 | 69 | 122 | -------------------------------------------------------------------------------- /src/components/Table.vue: -------------------------------------------------------------------------------- 1 | 2 | 83 | 84 | 174 | 189 | -------------------------------------------------------------------------------- /src/components/TableDetail.vue: -------------------------------------------------------------------------------- 1 | 2 | 71 | 72 | 136 | 137 | -------------------------------------------------------------------------------- /src/components/Tabs.vue: -------------------------------------------------------------------------------- 1 | 38 | 105 | 121 | -------------------------------------------------------------------------------- /src/components/TodoList.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 46 | 47 | 131 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue'; 2 | import { createPinia } from 'pinia'; 3 | 4 | import App from './App.vue'; 5 | import router from './router'; 6 | 7 | import './assets/main.css'; 8 | import ElementPlus from 'element-plus'; 9 | import 'element-plus/dist/index.css'; 10 | import * as echarts from 'echarts'; 11 | import axios from 'axios'; 12 | import VXETable from 'vxe-table'; 13 | import 'vxe-table/lib/style.css'; 14 | import * as ElementPlusIconsVue from '@element-plus/icons-vue'; 15 | 16 | const app = createApp(App); 17 | 18 | app.use(createPinia()); 19 | app.use(router); 20 | app.use(ElementPlus); 21 | app.use(VXETable); 22 | app.config.globalProperties.$echarts = echarts; 23 | app.config.globalProperties.$axios = axios; 24 | // 注册elementplus图标 25 | for (const [key, component] of Object.entries(ElementPlusIconsVue)) { 26 | app.component(key, component); 27 | } 28 | 29 | app.mount('#app'); 30 | -------------------------------------------------------------------------------- /src/router/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory } from 'vue-router'; 2 | import Login from '../views/Login.vue'; 3 | import Home from '../views/Home.vue'; 4 | 5 | const router = createRouter({ 6 | history: createWebHistory(import.meta.env.BASE_URL), 7 | routes: [ 8 | { 9 | path: '/login', 10 | name: 'Login', 11 | meta: { 12 | title: '登录', 13 | }, 14 | component: Login, 15 | }, 16 | { 17 | path: '/', 18 | redirect: '/dashboard', 19 | }, 20 | { 21 | path: '/', 22 | name: 'home', 23 | component: Home, 24 | children: [ 25 | { 26 | path: '/dashboard', 27 | name: 'dashboard', 28 | meta: { 29 | icon: 'Menu', 30 | name: '系统首页', 31 | }, 32 | component: () => import('../views/Dashboard.vue'), 33 | }, 34 | { 35 | path: '/search', 36 | name: 'search', 37 | meta: { 38 | parent: '/table', 39 | name: '搜索表格', 40 | }, 41 | children: [ 42 | { 43 | path: '/articles', 44 | name: 'articles', 45 | meta: { 46 | name: '搜索列表(文章)', 47 | }, 48 | component: () => import('../views/Articles.vue'), 49 | }, 50 | { 51 | path: '/projects', 52 | name: 'projects', 53 | meta: { 54 | name: '搜索列表(项目)', 55 | }, 56 | component: () => import('../views/Articles.vue'), 57 | }, 58 | { 59 | path: '/applications', 60 | name: 'applications', 61 | meta: { 62 | name: '搜索列表(文章)', 63 | }, 64 | component: () => import('../views/Articles.vue'), 65 | }, 66 | ], 67 | }, 68 | { 69 | path: '/table', 70 | name: 'table', 71 | meta: { 72 | title: '表格', 73 | name: '简单表格', 74 | icon: 'List', 75 | }, 76 | component: () => import('../views/Table.vue'), 77 | }, 78 | { 79 | path: '/complexTable', 80 | name: 'complexTable', 81 | meta: { 82 | name: '复杂表格', 83 | parent: '/table', 84 | }, 85 | component: () => import('../views/ComplexTable.vue'), 86 | }, 87 | { 88 | path: '/basicForm', 89 | name: 'basicForm', 90 | meta: { 91 | title: '表单', 92 | name: '基础表单', 93 | icon: 'Document', 94 | }, 95 | component: () => import('../views/BasicForm.vue'), 96 | }, 97 | { 98 | path: '/stepForm', 99 | name: 'stepForm', 100 | meta: { 101 | name: '分步表单', 102 | parent: '/basicForm', 103 | }, 104 | component: () => import('../views/StepForm.vue'), 105 | }, 106 | { 107 | path: '/user', 108 | name: 'user', 109 | meta: { 110 | icon: 'UserFilled', 111 | title: '个人中心', 112 | }, 113 | component: () => import('../views/AccountCenter.vue'), 114 | }, 115 | ], 116 | }, 117 | { 118 | path: '/:pathMatch(.*)*', 119 | redirect: '/not-found', 120 | }, 121 | { 122 | path: '/not-found', 123 | name: 'not-found', 124 | meta: { 125 | title: '未知页面', 126 | }, 127 | component: () => import('../views/NotFound.vue'), 128 | }, 129 | ], 130 | }); 131 | 132 | router.beforeEach((to, from, next) => { 133 | const islogin = sessionStorage.getItem('token'); 134 | if (!islogin && to.path !== '/login') { 135 | next('/login'); 136 | } else { 137 | next(); 138 | } 139 | }); 140 | export default router; 141 | -------------------------------------------------------------------------------- /src/stores/counter.ts: -------------------------------------------------------------------------------- 1 | import { ref, computed } from 'vue'; 2 | import { defineStore } from 'pinia'; 3 | 4 | export const useCounterStore = defineStore('counter', () => { 5 | const count = ref(0); 6 | const doubleCount = computed(() => count.value * 2); 7 | function increment() { 8 | count.value++; 9 | } 10 | 11 | return { count, doubleCount, increment }; 12 | }); 13 | -------------------------------------------------------------------------------- /src/stores/tabs.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia'; 2 | 3 | interface ListItem { 4 | name: string; 5 | path: string; 6 | title: string; 7 | fixed: boolean; 8 | } 9 | 10 | export const useTabsStore = defineStore('tabs', { 11 | state: () => { 12 | return { 13 | list: [], 14 | }; 15 | }, 16 | actions: { 17 | delTabsItem(index: number) { 18 | this.list.splice(index, 1); 19 | }, 20 | setTabsItem(data: ListItem) { 21 | this.list.push(data); 22 | }, 23 | delAllTabs() { 24 | this.list = []; 25 | }, 26 | delExcept(index: number) { 27 | this.list = [this.list[index]]; 28 | }, 29 | fixedTabsItem(index: number) { 30 | const item = this.list[index]; 31 | item.fixed = true; 32 | this.list.splice(index, 1); 33 | this.list.unshift(item); 34 | }, 35 | cancelFixedTabs(index: number) { 36 | const item = this.list[index]; 37 | item.fixed = false; 38 | }, 39 | }, 40 | }); 41 | -------------------------------------------------------------------------------- /src/stores/todos.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia'; 2 | 3 | export interface ListItem { 4 | id: number; 5 | content: string; 6 | complete: boolean; 7 | } 8 | 9 | export const useTodos = defineStore('todos', { 10 | state: () => ({ 11 | id: 3, 12 | todoList: [ 13 | { 14 | id: 0, 15 | content: '路由管理', 16 | complete: true, 17 | }, 18 | { 19 | id: 1, 20 | content: '首页图表', 21 | complete: false, 22 | }, 23 | { 24 | id: 2, 25 | content: '首页todoList', 26 | complete: false, 27 | }, 28 | ], 29 | }), 30 | actions: { 31 | addTodo(value: string) { 32 | this.todoList.push({ id: this.id++, content: value, complete: false }); 33 | }, 34 | delTodo(itemId: number) { 35 | this.todoList = this.todoList.filter((item) => item.id !== itemId); 36 | }, 37 | }, 38 | }); 39 | -------------------------------------------------------------------------------- /src/views/AccountCenter.vue: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 20 | 21 | 29 | -------------------------------------------------------------------------------- /src/views/Articles.vue: -------------------------------------------------------------------------------- 1 | 2 | 80 | 81 | 174 | 207 | -------------------------------------------------------------------------------- /src/views/BasicForm.vue: -------------------------------------------------------------------------------- 1 | 2 | 72 | 73 | 154 | 155 | 164 | -------------------------------------------------------------------------------- /src/views/ComplexTable.vue: -------------------------------------------------------------------------------- 1 | 2 | 54 | 55 | 349 | 350 | -------------------------------------------------------------------------------- /src/views/Dashboard.vue: -------------------------------------------------------------------------------- 1 | 292 | 359 | 360 | 427 | -------------------------------------------------------------------------------- /src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 94 | 95 | 135 | -------------------------------------------------------------------------------- /src/views/Login.vue: -------------------------------------------------------------------------------- 1 | 104 | 105 | 202 | 334 | -------------------------------------------------------------------------------- /src/views/NotFound.vue: -------------------------------------------------------------------------------- 1 | 9 | 16 | 17 | 36 | -------------------------------------------------------------------------------- /src/views/StepForm.vue: -------------------------------------------------------------------------------- 1 | 2 | 125 | 126 | 157 | 196 | -------------------------------------------------------------------------------- /src/views/Table.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/views/User.vue: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tsconfig.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.node.json", 3 | "include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "playwright.config.*"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "types": ["node"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.web.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "paths": { 7 | "@/*": ["./src/*"] 8 | }, 9 | "types": ["element-plus/global"] 10 | }, 11 | 12 | "references": [ 13 | { 14 | "path": "./tsconfig.config.json" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [ 3 | {"source": "/(.*)", "destination": "/index.html"} 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url'; 2 | 3 | import { defineConfig } from 'vite'; 4 | import vue from '@vitejs/plugin-vue'; 5 | import vueJsx from '@vitejs/plugin-vue-jsx'; 6 | 7 | // https://vitejs.dev/config/ 8 | export default defineConfig({ 9 | plugins: [vue(), vueJsx()], 10 | resolve: { 11 | alias: { 12 | '@': fileURLToPath(new URL('./src', import.meta.url)), 13 | }, 14 | }, 15 | }); 16 | --------------------------------------------------------------------------------