This commit is contained in:
13218645326 2023-11-30 13:40:30 +08:00
parent 666a603783
commit 06094b0b3d
97 changed files with 2935 additions and 5527 deletions

View File

@ -1,10 +0,0 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
['init', 'build', 'ci', 'chore', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test'],
],
},
};

View File

@ -1,16 +0,0 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*] # 表示所有文件都要遵循
indent_style = space # 缩进风格可选配置有space和tab
indent_size = 2 # 缩进大小
end_of_line = lf # 换行符可选配置有lf、cr和crlf
charset = utf-8 # 编码格式通常都是选utf-8
trim_trailing_whitespace = true # 去除多余的空格
insert_final_newline = true # 在尾部插入一行
[*.md] # 表示仅 md 文件适用
insert_final_newline = false # 在尾部插入一行
trim_trailing_whitespace = false # 去除多余的空格

7
.env
View File

@ -1,7 +0,0 @@
VITE_API_BASEURL = /api
VITE_BASE = /
VITE_APP_TITLE = Vitecamp
VITE_APP_DESCRIPTION = A zero-config Vue3 template includes Vite3、Vue3 and TypeScript

View File

View File

@ -1,9 +0,0 @@
node_modules
.DS_Store
dist
dist-ssr
*.local
presets
*.d.ts
src

View File

@ -1,228 +0,0 @@
{
"globals": {
"acceptHMRUpdate": true,
"asyncComputed": true,
"autoResetRef": true,
"biSyncRef": true,
"computed": true,
"computedInject": true,
"controlledComputed": true,
"controlledRef": true,
"createApp": true,
"createEventHook": true,
"createGlobalState": true,
"createPinia": true,
"createReactiveFn": true,
"createSharedComposable": true,
"createUnrefFn": true,
"customRef": true,
"debouncedRef": true,
"debouncedWatch": true,
"defineAsyncComponent": true,
"defineComponent": true,
"defineStore": true,
"eagerComputed": true,
"effectScope": true,
"EffectScope": true,
"ElMessage": true,
"ElNotification": true,
"extendRef": true,
"getActivePinia": true,
"getCurrentInstance": true,
"getCurrentScope": true,
"h": true,
"ignorableWatch": true,
"inject": true,
"isDefined": true,
"isReadonly": true,
"isRef": true,
"makeDestructurable": true,
"mapActions": true,
"mapGetters": true,
"mapState": true,
"mapStores": true,
"mapWritableState": true,
"markRaw": true,
"nextTick": true,
"onActivated": true,
"onBeforeMount": true,
"onBeforeUnmount": true,
"onBeforeUpdate": true,
"onClickOutside": true,
"onDeactivated": true,
"onErrorCaptured": true,
"onKeyStroke": true,
"onLongPress": true,
"onMounted": true,
"onRenderTracked": true,
"onRenderTriggered": true,
"onScopeDispose": true,
"onServerPrefetch": true,
"onStartTyping": true,
"onUnmounted": true,
"onUpdated": true,
"pausableWatch": true,
"provide": true,
"reactify": true,
"reactifyObject": true,
"reactive": true,
"reactiveComputed": true,
"reactiveOmit": true,
"reactivePick": true,
"readonly": true,
"ref": true,
"refDefault": true,
"resolveComponent": true,
"setActivePinia": true,
"setMapStoreSuffix": true,
"shallowReactive": true,
"shallowReadonly": true,
"shallowRef": true,
"storeToRefs": true,
"syncRef": true,
"templateRef": true,
"throttledRef": true,
"throttledWatch": true,
"toRaw": true,
"toReactive": true,
"toRef": true,
"toRefs": true,
"triggerRef": true,
"tryOnBeforeUnmount": true,
"tryOnMounted": true,
"tryOnScopeDispose": true,
"tryOnUnmounted": true,
"unref": true,
"unrefElement": true,
"until": true,
"useActiveElement": true,
"useAsyncQueue": true,
"useAsyncState": true,
"useAttrs": true,
"useBase64": true,
"useBattery": true,
"useBreakpoints": true,
"useBroadcastChannel": true,
"useBrowserLocation": true,
"useCached": true,
"useClamp": true,
"useClipboard": true,
"useColorMode": true,
"useConfirmDialog": true,
"useCounter": true,
"useCssModule": true,
"useCssVar": true,
"useCssVars": true,
"useCycleList": true,
"useDark": true,
"useDebounce": true,
"useDebouncedRefHistory": true,
"useDebounceFn": true,
"useDeviceMotion": true,
"useDeviceOrientation": true,
"useDevicePixelRatio": true,
"useDevicesList": true,
"useDisplayMedia": true,
"useDocumentVisibility": true,
"useDraggable": true,
"useElementBounding": true,
"useElementByPoint": true,
"useElementHover": true,
"useElementSize": true,
"useElementVisibility": true,
"useEventBus": true,
"useEventListener": true,
"useEventSource": true,
"useEyeDropper": true,
"useFavicon": true,
"useFetch": true,
"useFocus": true,
"useFocusWithin": true,
"useFps": true,
"useFullscreen": true,
"useGeolocation": true,
"useI18n": true,
"useIdle": true,
"useInfiniteScroll": true,
"useIntersectionObserver": true,
"useInterval": true,
"useIntervalFn": true,
"useKeyModifier": true,
"useLastChanged": true,
"useLocalStorage": true,
"useMagicKeys": true,
"useManualRefHistory": true,
"useMediaControls": true,
"useMediaQuery": true,
"useMemoize": true,
"useMemory": true,
"useMounted": true,
"useMouse": true,
"useMouseInElement": true,
"useMousePressed": true,
"useMutationObserver": true,
"useNavigatorLanguage": true,
"useNetwork": true,
"useNow": true,
"useOffsetPagination": true,
"useOnline": true,
"usePageLeave": true,
"useParallax": true,
"usePermission": true,
"usePointer": true,
"usePointerSwipe": true,
"usePreferredColorScheme": true,
"usePreferredDark": true,
"usePreferredLanguages": true,
"useRafFn": true,
"useRefHistory": true,
"useResizeObserver": true,
"useRoute": true,
"useRouter": true,
"useScreenSafeArea": true,
"useScriptTag": true,
"useScroll": true,
"useScrollLock": true,
"useSessionStorage": true,
"useShare": true,
"useSlots": true,
"useSpeechRecognition": true,
"useSpeechSynthesis": true,
"useStorage": true,
"useStorageAsync": true,
"useStyleTag": true,
"useSwipe": true,
"useTemplateRefsList": true,
"useTextSelection": true,
"useThrottle": true,
"useThrottledRefHistory": true,
"useThrottleFn": true,
"useTimeAgo": true,
"useTimeout": true,
"useTimeoutFn": true,
"useTimestamp": true,
"useTitle": true,
"useToggle": true,
"useTransition": true,
"useUrlSearchParams": true,
"useUserMedia": true,
"useVibrate": true,
"useVirtualList": true,
"useVModel": true,
"useVModels": true,
"useWakeLock": true,
"useWebNotification": true,
"useWebSocket": true,
"useWebWorker": true,
"useWebWorkerFn": true,
"useWindowFocus": true,
"useWindowScroll": true,
"useWindowSize": true,
"watch": true,
"watchAtMost": true,
"watchEffect": true,
"watchOnce": true,
"watchWithFilter": true,
"whenever": true
}
}

View File

@ -1,36 +0,0 @@
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
globals: {
defineEmits: true,
document: true,
localStorage: true,
GLOBAL_VAR: true,
window: true,
defineProps: true,
defineExpose: true,
withDefaults: true,
},
extends: [
'./.eslintrc-auto-import.json',
'airbnb-base',
'plugin:@typescript-eslint/recommended',
'plugin:vue/vue3-recommended',
'plugin:prettier/recommended', // 添加 prettier 插件
],
parserOptions: {
ecmaVersion: 'latest',
parser: '@typescript-eslint/parser',
sourceType: 'module',
},
plugins: ['vue', '@typescript-eslint', 'import'],
rules: {
'no-console': 'off',
'import/no-unresolved': 'off',
'import/extensions': 'off',
'import/no-extraneous-dependencies': 'off',
},
};

1
.gitattributes vendored
View File

@ -1 +0,0 @@
* text=auto eol=lf

23
.gitignore vendored
View File

@ -1,5 +1,28 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

1
.husky/.gitignore vendored
View File

@ -1 +0,0 @@
_

View File

@ -1,4 +0,0 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit $1

View File

@ -1,4 +0,0 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged

2
.npmrc
View File

@ -1,2 +0,0 @@
shamefully-hoist=true
strict-peer-dependencies=false

View File

@ -1,7 +0,0 @@
node_modules
.DS_Store
dist
dist-ssr
*.local
*.d.ts

View File

@ -1,12 +1,3 @@
{
"recommendations": [
"johnsoncodehk.volar",
"lokalise.i18n-ally",
"antfu.iconify",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"EditorConfig.EditorConfig",
"voorjaar.windicss-intellisense",
"csstools.postcss"
]
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
}

11
.vscode/settings.json vendored
View File

@ -1,11 +0,0 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
},
"editor.formatOnSave": true,
"i18n-ally.localesPaths": [
"locales"
],
"scss.lint.unknownAtRules": "ignore"
}

21
LICENSE
View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2022 菜猫子neko
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

134
README.md
View File

@ -1,130 +1,40 @@
<br>
# vue3PcTemplate
<p align='center'>
<a href="https://vitecamp.netlify.app/">Live Demo</a>
</p>
This template should help get you started developing with Vue 3 in Vite.
<br>
## Recommended IDE Setup
<p align='center'>
<b>English</b> | <a href="https://github.com/nekobc1998923/vitecamp/blob/master/README.zh-CN.md">简体中文</a>
</p>
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
<br>
## Type Support for `.vue` Imports in TS
## Features
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
- ⚡️ [Vue 3](https://github.com/vuejs/core), [Vite 3](https://github.com/vitejs/vite), [pnpm](https://pnpm.io/), [ESBuild](https://github.com/evanw/esbuild) - fast and faster !
- 💪 [Typescript](https://www.typescriptlang.org/) - of course! necessary
- 🎉 [Element Plus ready](https://github.com/element-plus/element-plus) - UI Library based on Vue.js 3
- 🔥 [Axios](https://github.com/axios/axios) - Http Library based on Promise
- 💡 [Vue Router 4](https://router.vuejs.org/zh/) - The official router for Vue.js
- 📦 [Components auto importing](https://github.com/antfu/unplugin-vue-components) - Automatically register components on demand without import
- 📥 [Auto import APIs](https://github.com/antfu/unplugin-auto-import) - Automatically import APIs
- 🍍 [State Management via Pinia](https://pinia.esm.dev/) - The Vue Store that you will enjoy using
- 🎨 [Windi CSS](https://github.com/windicss/windicss) - next generation utility-first CSS framework
- 😃 [icones](https://github.com/antfu/unplugin-icons) - Powerful Icon Library, Use icons from any icon sets
- 🌍 [I18n ready](./locales) - Want to translate? Yes, you can!
- 👩‍🎨 [NProgress](https://github.com/rstacruz/nprogress) - Page loading progress feedback
- 😃 [SVG Support](https://github.com/jpkleemans/vite-svg-loader) - Support the use of SVG images as components
- 📑 [Markdown Support](https://github.com/antfu/vite-plugin-md) - Markdown as components / components in Markdown
- 🔑 Complete code style specification and code submission specification
- ☁️ Deploy on Netlify, zero-config
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
## Pre-packed
1. Disable the built-in TypeScript Extension
1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
### UI Frameworks
## Customize configuration
- [Windi CSS](https://github.com/windicss/windicss) (On-demand [TailwindCSS](https://tailwindcss.com/)) - lighter and faster, with a bunch of additional features
- [Windi CSS Typography](https://windicss.org/plugins/official/typography.html)
- [Element Plus](https://github.com/element-plus/element-plus) - A powerful Vue.js 3 UI Library
See [Vite Configuration Reference](https://vitejs.dev/config/).
### Icons
## Project Setup
- [🔍Icônes](https://icones.netlify.app/) - use icons from any icon sets
- [unplugin-icons](https://github.com/antfu/unplugin-icons) - Automatically introduce the icons you need on demand
### Plugins
- [Vue Router 4](https://router.vuejs.org/zh/) - The official router for Vue.js
- [Pinia](https://pinia.esm.dev) - The Vue Store that you will enjoy using
- [Axios](https://github.com/axios/axios) - Http Library based on Promise
- [unplugin-vue-components](https://github.com/antfu/unplugin-vue-components) - components auto import
- [unplugin-auto-import](https://github.com/antfu/unplugin-auto-import) - Automatically import APIs
- [vite-plugin-windicss](https://github.com/antfu/vite-plugin-windicss) - Windi CSS Integration
- [vite-plugin-vue-markdown](https://github.com/antfu/vite-plugin-vue-markdown) - Markdown as components / components in Markdown
- [markdown-it-prism](https://github.com/jGleitz/markdown-it-prism) - [Prism](https://prismjs.com/) for syntax highlighting
- [prism-theme-vars](https://github.com/antfu/prism-theme-vars) - customizable Prism.js theme using CSS variables
- [markdown-it-link-attributes](https://github.com/crookedneighbor/markdown-it-link-attributes) - Uniformly set the hyperlink jump mode in markdown
- [Vue I18n](https://github.com/intlify/vue-i18n-next) - Internationalization
- [vite-plugin-vue-i18n](https://github.com/intlify/vite-plugin-vue-i18n) - Vite plugin for Vue I18n
- [vite-plugin-fonts](https://github.com/stafyniaksacha/vite-plugin-fonts) - Vite's font loader
- [VueUse](https://github.com/antfu/vueuse) - Collection of useful composition APIs
- [vite-svg-loader](https://github.com/jpkleemans/vite-svg-loader) - Support the use of SVG images as components
### Coding Style
- [ESLint](https://eslint.org/) with [Airbnb Style](https://github.com/airbnb/javascript)
### Dev tools
- [TypeScript](https://www.typescriptlang.org/)
- [Netlify](https://www.netlify.com/) - zero-config deployment
- [VS Code Extensions](./.vscode/extensions.json)
- [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) -Vue 3 IDE support
- [Iconify IntelliSense](https://marketplace.visualstudio.com/items?itemName=antfu.iconify) - Icon inline display and autocomplete
- [i18n Ally](https://marketplace.visualstudio.com/items?itemName=lokalise.i18n-ally) - All in one i18n support
- [Windi CSS Intellisense](https://marketplace.visualstudio.com/items?itemName=voorjaar.windicss-intellisense) - IDE support for Windi CSS
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - Code quality and rule checking
- [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) - Focus on code formatting and beautifying code
- [EditorConfig for VS Code](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) - Coding style check
## Try it now!
### GitHub Template
[Create a repo from this template on GitHub](https://github.com/nekobc1998923/vitecamp/generate).
### Clone to local
```bash
git clone https://github.com/nekobc1998923/vitecamp.git my-vitecamp-app
cd my-vitecamp-app
pnpm i
```sh
npm install
```
## Checklist
### Compile and Hot-Reload for Development
When you use this template, try follow the checklist to update your info properly
- [ ] Change the author name in `LICENSE`
- [ ] Change the author name in `package.json`
- [ ] Change the title in `.env`
- [ ] Change the favicon in `public`
- [ ] Clean up the `README` and remove routes
And then , you can enjoy coding fun :)
## Usage
### Development
Just run and visit http://localhost:8080
```bash
pnpm run dev
```sh
npm run dev
```
### Build
### Type-Check, Compile and Minify for Production
To build the App, run
```bash
pnpm run build
```sh
npm run build
```
And you will see the generated file in `dist` that ready to be served.
## Thanks
This template has some features inspired by [Vitesse](https://github.com/antfu/vitesse) ❤

View File

@ -1,126 +0,0 @@
<br>
<p align='center'>
<a href="https://vitecamp.netlify.app/">在线 Demo</a>
</p>
<br>
<p align='center'>
<a href="https://github.com/nekobc1998923/vitecamp/blob/master/README.md">English</a> | <b>简体中文</b>
</p>
<br>
## 特性
- ⚡️ [Vue 3](https://github.com/vuejs/core), [Vite 3](https://github.com/vitejs/vite), [pnpm](https://pnpm.io/), [ESBuild](https://github.com/evanw/esbuild) - 快,且更快!
- 💪 [Typescript](https://www.typescriptlang.org/) - 当然!必不可少
- 🎉 [Element Plus 开箱即用](https://github.com/element-plus/element-plus) - 基于 Vue.js 3 的强大 UI 库
- 🔥 [Axios 配置和封装](https://github.com/axios/axios) - 基于 Promise 的 HTTP 请求库
- 💡 [Vue Router 4](https://router.vuejs.org/zh/) - Vuejs 的官方路由
- 📦 [组件自动按需加载](https://github.com/antfu/unplugin-vue-components) - 自动按需注册组件, 无需 import
- 📥 [API 自动按需加载](https://github.com/antfu/unplugin-auto-import) - 无需手动 import 进行引入
- 🍍 [Pinia 状态管理](https://pinia.esm.dev/) - 你将会喜欢上的 Vue Store
- 🎨 [Windi CSS](https://github.com/windicss/windicss) - 下一代实用的原子 css 框架
- 😃 [icones](https://github.com/antfu/unplugin-icons) - 强大的图标库,各种图标集为你所用
- 🌍 [I18n 国际化开箱即用](./locales) - 想要翻译?是的,都可以!
- 👩‍🎨 [NProgress](https://github.com/rstacruz/nprogress) - 页面加载进度反馈
- 😃 [SVG 支持](https://github.com/jpkleemans/vite-svg-loader) - 支持以 组件形式使用 SVG 图片
- 📑 [Markdown 支持](https://github.com/antfu/vite-plugin-md) - 随意的在页面中嵌入 Markdown
- 🔑 完整支持的代码风格规范和代码提交规范
- ☁️ 支持零配置部署 Netlify
## 已配置
### UI 框架
- [Windi CSS](https://github.com/windicss/windicss) (按需的 [TailwindCSS](https://tailwindcss.com/)) - 更轻,更快和和一系列额外的特性!
- [Windi CSS Typography](https://windicss.org/plugins/official/typography.html)
- [Element Plus](https://github.com/element-plus/element-plus) - 基于 Vue.js 3 的强大 UI 库
### Icons
- [🔍Icônes](https://icones.netlify.app/) - 使用任意的图标集
- [unplugin-icons](https://github.com/antfu/unplugin-icons) - 自动按需引入你所需要的图标!
### 插件
- [Vue Router 4](https://router.vuejs.org/zh/) - Vuejs 的官方路由
- [Pinia](https://pinia.esm.dev) - 新一代的 Vue Store 状态管理
- [Axios](https://github.com/axios/axios) - 基于 Promise 的 HTTP 请求库
- [unplugin-vue-components](https://github.com/antfu/unplugin-vue-components) - 自动按需加载组件
- [unplugin-auto-import](https://github.com/antfu/unplugin-auto-import) - 自动按需加载 API
- [vite-plugin-windicss](https://github.com/antfu/vite-plugin-windicss) - Windi CSS 的整合
- [vite-plugin-vue-markdown](https://github.com/antfu/vite-plugin-vue-markdown) - Markdown 作为组件,也可以让组件在 Markdown 中使用
- [markdown-it-prism](https://github.com/jGleitz/markdown-it-prism) - [Prism](https://prismjs.com/) 的语法高亮
- [prism-theme-vars](https://github.com/antfu/prism-theme-vars) - 利用 CSS 变量自定义 Prism.js 的主题
- [markdown-it-link-attributes](https://github.com/crookedneighbor/markdown-it-link-attributes) - 统一设置 Markdown 里的超链接跳转方式
- [Vue I18n](https://github.com/intlify/vue-i18n-next) - 国际化
- [vite-plugin-vue-i18n](https://github.com/intlify/vite-plugin-vue-i18n) - Vue I18n 的 Vite 插件
- [vite-plugin-fonts](https://github.com/stafyniaksacha/vite-plugin-fonts) - Vite 的字体加载器
- [VueUse](https://github.com/antfu/vueuse) - 实用的 Composition API 工具合集
- [vite-svg-loader](https://github.com/jpkleemans/vite-svg-loader) - 支持以 组件形式使用 SVG 图片
### 编码风格
- [ESLint](https://eslint.org/) 配置为 [Airbnb Style](https://github.com/airbnb/javascript)
### 开发工具
- [TypeScript](https://www.typescriptlang.org/)
- [Netlify](https://www.netlify.com/) - 零配置的部署
- [VS Code 扩展](./.vscode/extensions.json)
- [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) - Vue 3 IDE 支持
- [Iconify IntelliSense](https://marketplace.visualstudio.com/items?itemName=antfu.iconify) - 图标内联显示和自动补全
- [i18n Ally](https://marketplace.visualstudio.com/items?itemName=lokalise.i18n-ally) - 多合一的 I18n 支持
- [Windi CSS 智能感知](https://marketplace.visualstudio.com/items?itemName=voorjaar.windicss-intellisense) - Windi CSS 的 IDE 支持
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - 代码质量和规则检查
- [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) - 专注于代码格式化、美化代码
- [EditorConfig for VS Code](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) - 编码风格检查
## 现在可以试试!
### GitHub 模板
[使用这个模板创建仓库](https://github.com/nekobc1998923/vitecamp/generate).
### 克隆到本地
```bash
git clone https://github.com/nekobc1998923/vitecamp.git my-vitecamp-app
cd my-vitecamp-app
pnpm i
```
## 清单
使用此模板时,请尝试按照清单正确更新你自己的信息
- [ ] 在 `LICENSE` 中改变作者名
- [ ] 在 `package.json` 中改变作者名
- [ ] 在 `.env` 中改变标题
- [ ] 在 `public` 目录下改变 favicon
- [ ] 整理 `README `并删除路由
然后,你就可以享受编写代码的乐趣了 :)
## 使用
### 开发
只需要执行以下命令就可以在 http://localhost:8080 中看到
```bash
pnpm run dev
```
### 构建
构建该应用只需要执行以下命令
```bash
pnpm run build
```
然后你会看到用于发布的 `dist` 文件夹被生成。

83
auto-imports.d.ts vendored Normal file
View File

@ -0,0 +1,83 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const createPinia: typeof import('pinia')['createPinia']
const customRef: typeof import('vue')['customRef']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const defineStore: typeof import('pinia')['defineStore']
const effectScope: typeof import('vue')['effectScope']
const getActivePinia: typeof import('pinia')['getActivePinia']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const mapActions: typeof import('pinia')['mapActions']
const mapGetters: typeof import('pinia')['mapGetters']
const mapState: typeof import('pinia')['mapState']
const mapStores: typeof import('pinia')['mapStores']
const mapWritableState: typeof import('pinia')['mapWritableState']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const resolveComponent: typeof import('vue')['resolveComponent']
const setActivePinia: typeof import('pinia')['setActivePinia']
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const storeToRefs: typeof import('pinia')['storeToRefs']
const toRaw: typeof import('vue')['toRaw']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const toValue: typeof import('vue')['toValue']
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useLink: typeof import('vue-router')['useLink']
const useRoute: typeof import('vue-router')['useRoute']
const useRouter: typeof import('vue-router')['useRouter']
const useSlots: typeof import('vue')['useSlots']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
}
// for type re-export
declare global {
// @ts-ignore
export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
import('vue')
}

24
components.d.ts vendored Normal file
View File

@ -0,0 +1,24 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
export {}
declare module 'vue' {
export interface GlobalComponents {
BarCom: typeof import('./src/components/echartsCom/barCom.vue')['default']
ElButton: typeof import('element-plus/es')['ElButton']
EquipmentLeasing: typeof import('./src/components/customCom/equipmentLeasing.vue')['default']
HotProvider: typeof import('./src/components/customCom/hotProvider.vue')['default']
LineCom: typeof import('./src/components/echarts/lineCom.vue')['default']
Map: typeof import('./src/components/echarts/map.vue')['default']
MapEcharts: typeof import('./src/components/echarts/mapEcharts.vue')['default']
MapEcharts2: typeof import('./src/components/echartsCom/mapEcharts2.vue')['default']
MapLine: typeof import('./src/components/mapBaidu/mapLine.vue')['default']
Pie3dCom: typeof import('./src/components/echartsCom/Pie3dCom.vue')['default']
Pie3dCom1: typeof import('./src/components/echartsCom/Pie3dCom1.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}

2
env.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
/// <reference types="vite/client" />
declare module "nprogress"

4
env/.env vendored Normal file
View File

@ -0,0 +1,4 @@
# port 端口号
VITE_PORT = 8888
# 自动打开浏览器
VITE_OPEN = true

6
env/.env.dev vendored Normal file
View File

@ -0,0 +1,6 @@
VITE_ENV = 'development'
VITE_BUILD_MODE = 'dev'
# 开发环境接口地址
VITE_API_URL = '/proxyApi'

6
env/.env.production vendored Normal file
View File

@ -0,0 +1,6 @@
VITE_ENV = 'production'
VITE_BUILD_MODE = 'prod'
# 线上环境接口地址
VITE_API_URL = 'https://production.com'

6
env/.env.sit vendored Normal file
View File

@ -0,0 +1,6 @@
VITE_ENV = 'production'
VITE_BUILD_MODE = 'sit'
# 线上环境接口地址
VITE_API_URL = 'https://testSit.com'

7
env/.env.uat vendored Normal file
View File

@ -0,0 +1,7 @@
# 线上环境
VITE_ENV = 'production'
VITE_BUILD_MODE = 'uat'
# 线上环境接口地址
VITE_API_URL = 'https://testUat.com'

View File

@ -0,0 +1,84 @@
{
"globals": {
"Component": true,
"ComponentPublicInstance": true,
"ComputedRef": true,
"EffectScope": true,
"ExtractDefaultPropTypes": true,
"ExtractPropTypes": true,
"ExtractPublicPropTypes": true,
"InjectionKey": true,
"PropType": true,
"Ref": true,
"VNode": true,
"WritableComputedRef": true,
"acceptHMRUpdate": true,
"computed": true,
"createApp": true,
"createPinia": true,
"customRef": true,
"defineAsyncComponent": true,
"defineComponent": true,
"defineStore": true,
"effectScope": true,
"getActivePinia": true,
"getCurrentInstance": true,
"getCurrentScope": true,
"h": true,
"inject": true,
"isProxy": true,
"isReactive": true,
"isReadonly": true,
"isRef": true,
"mapActions": true,
"mapGetters": true,
"mapState": true,
"mapStores": true,
"mapWritableState": true,
"markRaw": true,
"nextTick": true,
"onActivated": true,
"onBeforeMount": true,
"onBeforeRouteLeave": true,
"onBeforeRouteUpdate": true,
"onBeforeUnmount": true,
"onBeforeUpdate": true,
"onDeactivated": true,
"onErrorCaptured": true,
"onMounted": true,
"onRenderTracked": true,
"onRenderTriggered": true,
"onScopeDispose": true,
"onServerPrefetch": true,
"onUnmounted": true,
"onUpdated": true,
"provide": true,
"reactive": true,
"readonly": true,
"ref": true,
"resolveComponent": true,
"setActivePinia": true,
"setMapStoreSuffix": true,
"shallowReactive": true,
"shallowReadonly": true,
"shallowRef": true,
"storeToRefs": true,
"toRaw": true,
"toRef": true,
"toRefs": true,
"toValue": true,
"triggerRef": true,
"unref": true,
"useAttrs": true,
"useCssModule": true,
"useCssVars": true,
"useLink": true,
"useRoute": true,
"useRouter": true,
"useSlots": true,
"watch": true,
"watchEffect": true,
"watchPostEffect": true,
"watchSyncEffect": true
}
}

83
generated/auto-import.d.ts vendored Normal file
View File

@ -0,0 +1,83 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const createPinia: typeof import('pinia')['createPinia']
const customRef: typeof import('vue')['customRef']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const defineStore: typeof import('pinia')['defineStore']
const effectScope: typeof import('vue')['effectScope']
const getActivePinia: typeof import('pinia')['getActivePinia']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const mapActions: typeof import('pinia')['mapActions']
const mapGetters: typeof import('pinia')['mapGetters']
const mapState: typeof import('pinia')['mapState']
const mapStores: typeof import('pinia')['mapStores']
const mapWritableState: typeof import('pinia')['mapWritableState']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const resolveComponent: typeof import('vue')['resolveComponent']
const setActivePinia: typeof import('pinia')['setActivePinia']
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const storeToRefs: typeof import('pinia')['storeToRefs']
const toRaw: typeof import('vue')['toRaw']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const toValue: typeof import('vue')['toValue']
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useLink: typeof import('vue-router')['useLink']
const useRoute: typeof import('vue-router')['useRoute']
const useRouter: typeof import('vue-router')['useRouter']
const useSlots: typeof import('vue')['useSlots']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
}
// for type re-export
declare global {
// @ts-ignore
export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
import('vue')
}

View File

@ -1,9 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>

View File

@ -1,13 +0,0 @@
{
"hello": "Hello",
"welcome to": "Welcome to",
"includes features": "is a zero-config Vue3 template, it includes these feature",
"before coding": "Before coding",
"setup ide": "I recommended your IDE setup",
"home": "Home",
"change light": "Click to switch to bright color theme",
"change dark": "Click to switch to dark theme",
"change lang": "Switch languages",
"method to using": "Method of using template",
"template process": "Template configuration process"
}

View File

@ -1,13 +0,0 @@
{
"hello": "你好",
"welcome to": "欢迎来到",
"includes features": "是一个开箱即用的 Vue3 模板,它拥有这些功能:",
"before coding": "在开始编码之前",
"setup ide": "我建议将你的 IDE 设置为",
"home": "主页",
"change light": "点击切换为亮色主题",
"change dark": "点击切换为暗黑主题",
"change lang": "切换国际化语言",
"method to using": "使用模板的方法",
"template process": "模板配置流程"
}

View File

@ -1,68 +1,46 @@
{
"name": "vitecamp",
"name": "vue3pctemplate",
"version": "0.0.0",
"author": "菜猫子neko",
"packageManager": "pnpm@7.9.0",
"license": "MIT",
"private": true,
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit --skipLibCheck && vite build",
"lint": "eslint src",
"dev": "vite --mode dev",
"build": "npm run build:pro",
"build:sit": "vue-tsc && vite build --mode sit",
"build:uat": "vue-tsc && vite build --mode uat",
"build:pro": "vue-tsc && vite build --mode production",
"preview": "vite preview",
"prepare": "husky install"
"build-only": "vite build",
"type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false"
},
"dependencies": {
"@vueuse/core": "^8.9.2",
"axios": "^0.25.0",
"@vueuse/core": "^10.6.1",
"axios": "^1.6.2",
"echarts": "^5.4.3",
"element-plus": "^2.0.1",
"element-plus": "^2.4.3",
"highcharts": "^11.2.0",
"mitt": "^3.0.1",
"moment": "^2.29.4",
"nprogress": "^0.2.0",
"pinia": "^2.0.16",
"prism-theme-vars": "^0.2.4",
"vue": "^3.2.25",
"vue-i18n": "^9.1.9",
"vue-router": "^4.1.2"
"pinia": "^2.1.7",
"pinia-plugin-persist": "^1.0.0",
"sass": "^1.69.5",
"vite-plugin-html": "^3.2.0",
"vite-plugin-zip-file": "^2.2.0",
"vue": "^3.3.4",
"vue-router": "^4.2.5"
},
"devDependencies": {
"@commitlint/cli": "^16.1.0",
"@commitlint/config-conventional": "^16.0.0",
"@iconify/json": "^2.0.29",
"@intlify/vite-plugin-vue-i18n": "^6.0.0",
"@types/node": "^17.0.10",
"@types/nprogress": "^0.2.0",
"@types/svgo": "^2.6.1",
"@typescript-eslint/eslint-plugin": "^5.10.0",
"@typescript-eslint/parser": "^5.10.0",
"@vitejs/plugin-vue": "^3.0.1",
"@vitejs/plugin-vue-jsx": "2.0.0",
"eslint": "^8.19.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.3.0",
"husky": "^7.0.4",
"lint-staged": "^12.3.2",
"markdown-it-link-attributes": "^4.0.0",
"markdown-it-prism": "^2.2.2",
"pnpm": "^7.9.0",
"prettier": "^2.5.1",
"sass": "^1.49.0",
"typescript": "^4.4.4",
"unplugin-auto-import": "^0.9.2",
"unplugin-icons": "^0.14.8",
"unplugin-vue-components": "^0.21.1",
"vite": "^3.0.5",
"vite-plugin-fonts": "^0.6.0",
"vite-plugin-vue-markdown": "^0.21.1",
"vite-plugin-windicss": "^1.8.7",
"vite-svg-loader": "^3.4.0",
"vue-tsc": "^0.38.4"
},
"lint-staged": {
"*.{ts,js,vue}": [
"eslint"
]
"@tsconfig/node18": "^18.2.2",
"@types/node": "^18.18.5",
"@types/nprogress": "^0.2.3",
"@vitejs/plugin-vue": "^4.4.0",
"@vitejs/plugin-vue-jsx": "^3.0.2",
"@vue/tsconfig": "^0.4.0",
"npm-run-all2": "^6.1.1",
"typescript": "~5.2.0",
"unplugin-auto-import": "^0.17.1",
"unplugin-vue-components": "^0.25.2",
"vite": "^4.4.11",
"vue-tsc": "^1.8.19"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,79 +0,0 @@
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import svgLoader from 'vite-svg-loader';
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import Icons from 'unplugin-icons/vite';
import IconsResolver from 'unplugin-icons/resolver';
import { ElementPlusResolver, VueUseComponentsResolver } from 'unplugin-vue-components/resolvers';
import WindiCSS from 'vite-plugin-windicss';
import Markdown from 'vite-plugin-vue-markdown'
import Prism from 'markdown-it-prism';
import ViteFonts from 'vite-plugin-fonts';
import VueI18n from '@intlify/vite-plugin-vue-i18n';
import LinkAttributes from 'markdown-it-link-attributes';
import { ConfigEnv } from 'vite';
import { resolve } from 'path';
const defaultClasses = 'prose prose-sm m-auto text-left';
export default (env: ConfigEnv) => {
return [
vue({
include: [/\.vue$/, /\.md$/],
}),
vueJsx(),
svgLoader(),
AutoImport({
dts: './src/auto-imports.d.ts',
imports: ['vue', 'pinia', 'vue-router', 'vue-i18n', , '@vueuse/core'],
// Generate corresponding .eslintrc-auto-import.json file.
// eslint globals Docs - https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals
eslintrc: {
enabled: false, // Default `false`
filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
},
resolvers: [ElementPlusResolver()],
}),
Components({
dts: './src/components.d.ts',
extensions: ['vue', 'md'],
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
// imports 指定组件所在位置,默认为 src/components; 有需要也可以加上 view 目录
dirs: ['src/components/'],
resolvers: [ElementPlusResolver(), IconsResolver(), VueUseComponentsResolver()],
}),
Icons({
compiler: 'vue3',
autoInstall: true,
}),
ViteFonts({
google: {
families: ['Open Sans', 'Montserrat', 'Fira Sans'],
},
}),
VueI18n({
include: [resolve(__dirname, '../locales/**')],
}),
WindiCSS({
safelist: defaultClasses,
}),
Markdown({
wrapperClasses: defaultClasses,
headEnabled: false,
markdownItSetup(md) {
// https://prismjs.com/
md.use(Prism);
// 为 md 中的所有链接设置为 新页面跳转
md.use(LinkAttributes, {
matcher: (link: string) => /^https?:\/\//.test(link),
attrs: {
target: '_blank',
rel: 'noopener',
},
});
},
}),
];
};

View File

@ -1,29 +0,0 @@
// https://prettier.io/docs/en/configuration.html
module.exports = {
// 每一行的宽度(显示的字符数)
printWidth: 120,
// tab健的空格数
tabWidth: 2,
// 是否在对象中的括号之间打印空格,{a:5}格式化为{ a: 5 }
bracketSpacing: true,
// 箭头函数的参数无论有几个,都要括号包裹
arrowParens: 'always',
// 换行符的使用
endOfLine: 'lf',
// 是否用单引号, 项目中全部使用单引号
singleQuote: true,
// 对象或者数组的最后一个元素后面是否要加逗号
trailingComma: 'all',
// 是否加分号,项目中统一加分号
semi: true,
// 是否使用tab格式化 不使用
useTabs: false,
};

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--emojione" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 64 64"><path fill="#d6eef0" d="M0 0h64v64H0z"></path><g fill="#b2c1c0"><path d="M0 15l4-4l6.5-4L22 16l16 21H0z"></path><path opacity=".5" d="M38 37L22 16L10.5 7L9 14l4 4l-1 6l4 4l-2 9z"></path></g><path fill="#fff" d="M10.5 7L4 11l-2 2h3l-1.5 4.1L8 15l1 5l4-2l3.9 2v-3.5L22 16z"></path><path opacity=".5" fill="#b2c1c0" d="M38 37L22 16L10.5 7l-.5 5l3 6l-1 6l4 4l-2 9z"></path><g fill="#83bf4f"><path d="M0 32c.1 0 0 0 0 0"></path><path d="M50.2 34.5C47 33.1 43.6 32 40 32c-3.6 0-6.8 1.7-9.6 2.4C14 38.7 0 32 0 32v32h64V36.3c-4.4.5-9.2-.1-13.8-1.8"></path></g><g fill="#699635"><circle cx="5" cy="45" r="4"></circle><circle cx="6" cy="40" r="3"></circle><circle cx="12.2" cy="43" r="6"></circle></g><path fill="#89664c" d="M55.8 33.8h2.7V42h-2.7z"></path><path d="M59.4 22.9c-1.2-2.3-3.2-2.3-4.4 0l-4.2 7.8c-1.2 2.3 0 4.1 2.7 4.1c0 0 2.7-1 3.7-1s3.7 1 3.7 1c2.7 0 3.9-1.8 2.7-4.1l-4.2-7.8" fill="#699635"></path><path d="M58.9 18.4c-1-1.8-2.5-1.8-3.5 0l-3.3 6.3c-1 1.8 0 3.3 2.2 3.3c0 0 2.2-1 2.9-1s2.9 1 2.9 1c2.1 0 3.1-1.5 2.2-3.3l-3.4-6.3" fill="#75a843"></path><path d="M58.5 14c-.7-1.4-1.9-1.4-2.6 0l-2.5 4.7c-.7 1.4 0 2.5 1.6 2.5c0 0 1.6-1 2.2-1s2.2 1 2.2 1c1.6 0 2.3-1.1 1.6-2.5L58.5 14" fill="#83bf4f"></path><g fill="#fff"><path d="M34 7c0 1.1-.9 2-2 2H22c-1.1 0-2-.9-2-2s.9-2 2-2h10c1.1 0 2 .9 2 2"></path><path d="M38 9c0 1.1-.9 2-2 2h-4c-1.1 0-2-.9-2-2s.9-2 2-2h4c1.1 0 2 .9 2 2"></path><path d="M42 17c0 1.1-.9 2-2 2h-4c-1.1 0-2-.9-2-2s.9-2 2-2h4c1.1 0 2 .9 2 2"></path><path d="M52 12c0 1.1-.9 2-2 2h-4c-1.1 0-2-.9-2-2s.9-2 2-2h4c1.1 0 2 .9 2 2"></path></g><path fill="#ffdd7d" d="M30.8 36h18l7.4 13.4l-2.5 6.2l-15.4 2.6z"></path><path fill="#dbb471" d="M24.4 55l-1.3-5.7L30.8 36l8.7 16.6l-1.2 6.6z"></path><path fill="#89664c" d="M30.8 36L27 55.8l6.1 1.8z"></path><g fill="#ffdd7d"><path d="M30.8 36s1.4 12.1 3.7 16.6l-1.4 5L30.8 36"></path><path d="M27 55.8l-1.4-3.9s4.5-11.6 5.2-15.9L27 55.8z"></path></g><circle cx="19" cy="45" r="4" fill="#699635"></circle><path fill="#dbb471" d="M38.5 51.6l17.7-2.2l-1.5 7.2l-16.4 2.6z"></path></svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

BIN
src.zip

Binary file not shown.

View File

@ -1,14 +1,10 @@
<template>
<router-view></router-view>
<RouterView />
</template>
<script setup lang="ts">
const router = useRouter()
const toEcharts = () => {
router.push({
name: 'echartsScreen'
})
}
</script>
<style lang="scss">
@import "./assets//styles/index.scss";
</style>
@import url("./style/css/reset.css");
</style>

View File

@ -1,24 +0,0 @@
declare interface codeMessageMapTypes {
400: string;
401: string;
403: string;
404: string;
405: string;
500: string;
[key: string]: string;
}
const codeMessageMap: codeMessageMapTypes = {
400: '[400]:请求参数错误',
401: '[401]:账户未登录',
403: '[403]:拒绝访问',
404: '[404]:请求路径错误',
405: '[405]:请求方法错误',
500: '[500]:服务器错误',
};
const showCodeMessage = (code: number | string): string => {
return codeMessageMap[JSON.stringify(code)] || '网络连接异常,请稍后再试!';
};
export default showCodeMessage;

View File

@ -1,76 +0,0 @@
import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import showCodeMessage from '@/api/code';
import { formatJsonToUrlParams, instanceObject } from '@/utils/format';
const BASE_PREFIX = import.meta.env.VITE_API_BASEURL;
// 创建实例
const axiosInstance: AxiosInstance = axios.create({
// 前缀
baseURL: BASE_PREFIX,
// 超时
timeout: 1000 * 30,
// 请求头
headers: {
'Content-Type': 'application/json',
},
});
// 请求拦截器
axiosInstance.interceptors.request.use(
(config: AxiosRequestConfig) => {
// TODO 在这里可以加上想要在请求发送前处理的逻辑
// TODO 比如 loading 等
return config;
},
(error: AxiosError) => {
return Promise.reject(error);
},
);
// 响应拦截器
axiosInstance.interceptors.response.use(
(response: AxiosResponse) => {
if (response.status === 200) {
return response.data;
}
ElMessage.info(JSON.stringify(response.status));
return response;
},
(error: AxiosError) => {
const { response } = error;
if (response) {
ElMessage.error(showCodeMessage(response.status));
return Promise.reject(response.data);
}
ElMessage.warning('网络连接异常,请稍后再试!');
return Promise.reject(error);
},
);
const service = {
get<T = any>(url: string, data?: object): Promise<T> {
return axiosInstance.get(url, { params: data });
},
post<T = any>(url: string, data?: object): Promise<T> {
return axiosInstance.post(url, data);
},
put<T = any>(url: string, data?: object): Promise<T> {
return axiosInstance.put(url, data);
},
delete<T = any>(url: string, data?: object): Promise<T> {
return axiosInstance.delete(url, data);
},
upload: (url: string, file: FormData | File) =>
axiosInstance.post(url, file, {
headers: { 'Content-Type': 'multipart/form-data' },
}),
download: (url: string, data: instanceObject) => {
window.location.href = `${BASE_PREFIX}/${url}?${formatJsonToUrlParams(data)}`;
},
};
export default service;

View File

@ -1,8 +0,0 @@
import service from '@/api/http';
const loginApi = {
// 验证登录实例
postVerification: (params: object) => service.post(`/login`, params),
};
export default loginApi;

86
src/assets/base.css Normal file
View File

@ -0,0 +1,86 @@
/* color palette from <https://github.com/vuejs/theme> */
:root {
--vt-c-white: #ffffff;
--vt-c-white-soft: #f8f8f8;
--vt-c-white-mute: #f2f2f2;
--vt-c-black: #181818;
--vt-c-black-soft: #222222;
--vt-c-black-mute: #282828;
--vt-c-indigo: #2c3e50;
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
--vt-c-text-light-1: var(--vt-c-indigo);
--vt-c-text-light-2: rgba(60, 60, 60, 0.66);
--vt-c-text-dark-1: var(--vt-c-white);
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
}
/* semantic color variables for this project */
:root {
--color-background: var(--vt-c-white);
--color-background-soft: var(--vt-c-white-soft);
--color-background-mute: var(--vt-c-white-mute);
--color-border: var(--vt-c-divider-light-2);
--color-border-hover: var(--vt-c-divider-light-1);
--color-heading: var(--vt-c-text-light-1);
--color-text: var(--vt-c-text-light-1);
--section-gap: 160px;
}
@media (prefers-color-scheme: dark) {
:root {
--color-background: var(--vt-c-black);
--color-background-soft: var(--vt-c-black-soft);
--color-background-mute: var(--vt-c-black-mute);
--color-border: var(--vt-c-divider-dark-2);
--color-border-hover: var(--vt-c-divider-dark-1);
--color-heading: var(--vt-c-text-dark-1);
--color-text: var(--vt-c-text-dark-2);
}
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
font-weight: normal;
}
body {
min-height: 100vh;
color: var(--color-text);
background: var(--color-background);
transition:
color 0.5s,
background-color 0.5s;
line-height: 1.6;
font-family:
Inter,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
Oxygen,
Ubuntu,
Cantarell,
'Fira Sans',
'Droid Sans',
'Helvetica Neue',
sans-serif;
font-size: 15px;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

1
src/assets/logo.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>

After

Width:  |  Height:  |  Size: 276 B

263
src/auto-imports.d.ts vendored
View File

@ -1,263 +0,0 @@
// Generated by 'unplugin-auto-import'
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
const computed: typeof import('vue')['computed']
const computedAsync: typeof import('@vueuse/core')['computedAsync']
const computedEager: typeof import('@vueuse/core')['computedEager']
const computedInject: typeof import('@vueuse/core')['computedInject']
const computedWithControl: typeof import('@vueuse/core')['computedWithControl']
const controlledComputed: typeof import('@vueuse/core')['controlledComputed']
const controlledRef: typeof import('@vueuse/core')['controlledRef']
const createApp: typeof import('vue')['createApp']
const createEventHook: typeof import('@vueuse/core')['createEventHook']
const createGlobalState: typeof import('@vueuse/core')['createGlobalState']
const createInjectionState: typeof import('@vueuse/core')['createInjectionState']
const createPinia: typeof import('pinia')['createPinia']
const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn']
const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable']
const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn']
const customRef: typeof import('vue')['customRef']
const debouncedRef: typeof import('@vueuse/core')['debouncedRef']
const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const defineStore: typeof import('pinia')['defineStore']
const eagerComputed: typeof import('@vueuse/core')['eagerComputed']
const effectScope: typeof import('vue')['effectScope']
const extendRef: typeof import('@vueuse/core')['extendRef']
const getActivePinia: typeof import('pinia')['getActivePinia']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
const inject: typeof import('vue')['inject']
const isDefined: typeof import('@vueuse/core')['isDefined']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const logicAnd: typeof import('@vueuse/core')['logicAnd']
const logicNot: typeof import('@vueuse/core')['logicNot']
const logicOr: typeof import('@vueuse/core')['logicOr']
const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable']
const mapActions: typeof import('pinia')['mapActions']
const mapGetters: typeof import('pinia')['mapGetters']
const mapState: typeof import('pinia')['mapState']
const mapStores: typeof import('pinia')['mapStores']
const mapWritableState: typeof import('pinia')['mapWritableState']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onClickOutside: typeof import('@vueuse/core')['onClickOutside']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke']
const onLongPress: typeof import('@vueuse/core')['onLongPress']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onStartTyping: typeof import('@vueuse/core')['onStartTyping']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
const provide: typeof import('vue')['provide']
const reactify: typeof import('@vueuse/core')['reactify']
const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
const reactive: typeof import('vue')['reactive']
const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed']
const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit']
const reactivePick: typeof import('@vueuse/core')['reactivePick']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const refAutoReset: typeof import('@vueuse/core')['refAutoReset']
const refDebounced: typeof import('@vueuse/core')['refDebounced']
const refDefault: typeof import('@vueuse/core')['refDefault']
const refThrottled: typeof import('@vueuse/core')['refThrottled']
const refWithControl: typeof import('@vueuse/core')['refWithControl']
const resolveComponent: typeof import('vue')['resolveComponent']
const resolveRef: typeof import('@vueuse/core')['resolveRef']
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
const setActivePinia: typeof import('pinia')['setActivePinia']
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const storeToRefs: typeof import('pinia')['storeToRefs']
const syncRef: typeof import('@vueuse/core')['syncRef']
const syncRefs: typeof import('@vueuse/core')['syncRefs']
const templateRef: typeof import('@vueuse/core')['templateRef']
const throttledRef: typeof import('@vueuse/core')['throttledRef']
const throttledWatch: typeof import('@vueuse/core')['throttledWatch']
const toRaw: typeof import('vue')['toRaw']
const toReactive: typeof import('@vueuse/core')['toReactive']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const triggerRef: typeof import('vue')['triggerRef']
const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount']
const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount']
const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted']
const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose']
const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted']
const unref: typeof import('vue')['unref']
const unrefElement: typeof import('@vueuse/core')['unrefElement']
const until: typeof import('@vueuse/core')['until']
const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue']
const useAsyncState: typeof import('@vueuse/core')['useAsyncState']
const useAttrs: typeof import('vue')['useAttrs']
const useBase64: typeof import('@vueuse/core')['useBase64']
const useBattery: typeof import('@vueuse/core')['useBattery']
const useBluetooth: typeof import('@vueuse/core')['useBluetooth']
const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints']
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
const useCached: typeof import('@vueuse/core')['useCached']
const useClamp: typeof import('@vueuse/core')['useClamp']
const useClipboard: typeof import('@vueuse/core')['useClipboard']
const useColorMode: typeof import('@vueuse/core')['useColorMode']
const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog']
const useCounter: typeof import('@vueuse/core')['useCounter']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVar: typeof import('@vueuse/core')['useCssVar']
const useCssVars: typeof import('vue')['useCssVars']
const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement']
const useCycleList: typeof import('@vueuse/core')['useCycleList']
const useDark: typeof import('@vueuse/core')['useDark']
const useDateFormat: typeof import('@vueuse/core')['useDateFormat']
const useDebounce: typeof import('@vueuse/core')['useDebounce']
const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn']
const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory']
const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion']
const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation']
const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio']
const useDevicesList: typeof import('@vueuse/core')['useDevicesList']
const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia']
const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility']
const useDraggable: typeof import('@vueuse/core')['useDraggable']
const useDropZone: typeof import('@vueuse/core')['useDropZone']
const useElementBounding: typeof import('@vueuse/core')['useElementBounding']
const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint']
const useElementHover: typeof import('@vueuse/core')['useElementHover']
const useElementSize: typeof import('@vueuse/core')['useElementSize']
const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility']
const useEventBus: typeof import('@vueuse/core')['useEventBus']
const useEventListener: typeof import('@vueuse/core')['useEventListener']
const useEventSource: typeof import('@vueuse/core')['useEventSource']
const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper']
const useFavicon: typeof import('@vueuse/core')['useFavicon']
const useFetch: typeof import('@vueuse/core')['useFetch']
const useFileDialog: typeof import('@vueuse/core')['useFileDialog']
const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess']
const useFocus: typeof import('@vueuse/core')['useFocus']
const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin']
const useFps: typeof import('@vueuse/core')['useFps']
const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
const useGamepad: typeof import('@vueuse/core')['useGamepad']
const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
const useI18n: typeof import('vue-i18n')['useI18n']
const useIdle: typeof import('@vueuse/core')['useIdle']
const useImage: typeof import('@vueuse/core')['useImage']
const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll']
const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver']
const useInterval: typeof import('@vueuse/core')['useInterval']
const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn']
const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier']
const useLastChanged: typeof import('@vueuse/core')['useLastChanged']
const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage']
const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys']
const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory']
const useMediaControls: typeof import('@vueuse/core')['useMediaControls']
const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery']
const useMemoize: typeof import('@vueuse/core')['useMemoize']
const useMemory: typeof import('@vueuse/core')['useMemory']
const useMounted: typeof import('@vueuse/core')['useMounted']
const useMouse: typeof import('@vueuse/core')['useMouse']
const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement']
const useMousePressed: typeof import('@vueuse/core')['useMousePressed']
const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver']
const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage']
const useNetwork: typeof import('@vueuse/core')['useNetwork']
const useNow: typeof import('@vueuse/core')['useNow']
const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl']
const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination']
const useOnline: typeof import('@vueuse/core')['useOnline']
const usePageLeave: typeof import('@vueuse/core')['usePageLeave']
const useParallax: typeof import('@vueuse/core')['useParallax']
const usePermission: typeof import('@vueuse/core')['usePermission']
const usePointer: typeof import('@vueuse/core')['usePointer']
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
const useRafFn: typeof import('@vueuse/core')['useRafFn']
const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
const useRoute: typeof import('vue-router')['useRoute']
const useRouter: typeof import('vue-router')['useRouter']
const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation']
const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea']
const useScriptTag: typeof import('@vueuse/core')['useScriptTag']
const useScroll: typeof import('@vueuse/core')['useScroll']
const useScrollLock: typeof import('@vueuse/core')['useScrollLock']
const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage']
const useShare: typeof import('@vueuse/core')['useShare']
const useSlots: typeof import('vue')['useSlots']
const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition']
const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis']
const useStepper: typeof import('@vueuse/core')['useStepper']
const useStorage: typeof import('@vueuse/core')['useStorage']
const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync']
const useStyleTag: typeof import('@vueuse/core')['useStyleTag']
const useSwipe: typeof import('@vueuse/core')['useSwipe']
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
const useTextSelection: typeof import('@vueuse/core')['useTextSelection']
const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize']
const useThrottle: typeof import('@vueuse/core')['useThrottle']
const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn']
const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory']
const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo']
const useTimeout: typeof import('@vueuse/core')['useTimeout']
const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn']
const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll']
const useTimestamp: typeof import('@vueuse/core')['useTimestamp']
const useTitle: typeof import('@vueuse/core')['useTitle']
const useToggle: typeof import('@vueuse/core')['useToggle']
const useTransition: typeof import('@vueuse/core')['useTransition']
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
const useVModel: typeof import('@vueuse/core')['useVModel']
const useVModels: typeof import('@vueuse/core')['useVModels']
const useVibrate: typeof import('@vueuse/core')['useVibrate']
const useVirtualList: typeof import('@vueuse/core')['useVirtualList']
const useWakeLock: typeof import('@vueuse/core')['useWakeLock']
const useWebNotification: typeof import('@vueuse/core')['useWebNotification']
const useWebSocket: typeof import('@vueuse/core')['useWebSocket']
const useWebWorker: typeof import('@vueuse/core')['useWebWorker']
const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn']
const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus']
const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll']
const useWindowSize: typeof import('@vueuse/core')['useWindowSize']
const watch: typeof import('vue')['watch']
const watchArray: typeof import('@vueuse/core')['watchArray']
const watchAtMost: typeof import('@vueuse/core')['watchAtMost']
const watchDebounced: typeof import('@vueuse/core')['watchDebounced']
const watchEffect: typeof import('vue')['watchEffect']
const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable']
const watchOnce: typeof import('@vueuse/core')['watchOnce']
const watchPausable: typeof import('@vueuse/core')['watchPausable']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
const watchThrottled: typeof import('@vueuse/core')['watchThrottled']
const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable']
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
const whenever: typeof import('@vueuse/core')['whenever']
}

42
src/components.d.ts vendored
View File

@ -1,42 +0,0 @@
// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/core/pull/3399
import '@vue/runtime-core'
export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
3dPie: typeof import('./components/echartsCom/3dPie.vue')['default']
3dPieCom: typeof import('./components/echartsCom/3dPieCom.vue')['default']
BarCom: typeof import('./components/echartsCom/barCom.vue')['default']
copy: typeof import('./components/echartsCom/Pie3dCom copy.vue')['default']
ElButton: typeof import('element-plus/es')['ElButton']
ElCol: typeof import('element-plus/es')['ElCol']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElResult: typeof import('element-plus/es')['ElResult']
ElRow: typeof import('element-plus/es')['ElRow']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
EnProcess: typeof import('./components/EnProcess.md')['default']
EquipmentLeasing: typeof import('./components/customCom/equipmentLeasing.vue')['default']
HotProvider: typeof import('./components/customCom/hotProvider.vue')['default']
IAkarIconsGithubFill: typeof import('~icons/akar-icons/github-fill')['default']
ILaLanguage: typeof import('~icons/la/language')['default']
IMdiContentDuplicate: typeof import('~icons/mdi/content-duplicate')['default']
IMdiHomeSearchOutline: typeof import('~icons/mdi/home-search-outline')['default']
IPhCloudMoonBold: typeof import('~icons/ph/cloud-moon-bold')['default']
IPhSunHorizonBold: typeof import('~icons/ph/sun-horizon-bold')['default']
IRiArticleLine: typeof import('~icons/ri/article-line')['default']
LineCom: typeof import('./components/echarts/lineCom.vue')['default']
Map: typeof import('./components/echarts/map.vue')['default']
MapEcharts: typeof import('./components/echarts/mapEcharts.vue')['default']
MapEcharts2: typeof import('./components/echartsCom/mapEcharts2.vue')['default']
Pie3dCom: typeof import('./components/echartsCom/Pie3dCom.vue')['default']
Pie3dCom1: typeof import('./components/echartsCom/Pie3dCom1.vue')['default']
Pie3dCom2: typeof import('./components/echartsCom/Pie3dCom2.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
TheFooter: typeof import('./components/TheFooter.vue')['default']
ZhProcess: typeof import('./components/ZhProcess.md')['default']
}
}

44
src/env.d.ts vendored
View File

@ -1,44 +0,0 @@
/// <reference types="vite/client" />
/// <reference types="vite-svg-loader" />
// 声明自动引入的 vue 组件
declare module '*.vue' {
import { DefineComponent } from 'vue';
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>;
export default component;
}
// 声明 icons 引入的组件
declare module '~icons/*' {
import { FunctionalComponent, SVGAttributes } from 'vue';
const component: FunctionalComponent<SVGAttributes>;
export default component;
}
// 声明 md 文件
declare module '*.md' {
import type { DefineComponent } from 'vue';
const component: DefineComponent<{}, {}, any>;
export default component;
}
// 声明 vite 环境变量
declare interface ImportMetaEnv {
readonly VITE_BASE: string;
readonly VITE_API_BASEURL: string;
readonly VITE_APP_TITLE: string;
// 更多环境变量...
}
declare interface ImportMeta {
readonly env: ImportMetaEnv;
}
declare interface Window {
// extend the window
}
declare module "vue"
declare module "echarts"
declare module "highcharts"
declare module "Math"

View File

@ -2,7 +2,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import axios from 'axios'
import NProgress from 'nprogress'
import { useDebounceFn } from '@vueuse/core'
import { useStore } from 'store/main'
const store = useStore()
// const CancelToken = axios.CancelToken

View File

@ -1,31 +1,25 @@
// i18n
import { createI18n } from 'vue-i18n';
import messages from '@intlify/vite-plugin-vue-i18n/messages';
// vue router
import router from '@/router/index';
// pinia
import store from '@/store';
import App from './App.vue';
import 'virtual:windi.css';
// Devtools: https://windicss.org/integrations/vite.html#design-in-devtools
import 'virtual:windi-devtools';
import '@/assets/styles/index.scss';
// 引入charts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
import highcharts from 'highcharts';
// 使用3d图还需要引入下面的
import highcharts3d from 'highcharts/highcharts-3d';
// 调用3d图表
highcharts3d(highcharts);
const i18n = createI18n({
locale: 'en',
messages,
import BaiduMap from 'vue-baidu-map'
Vue.use(BaiduMap, {
ak: 'U4Bn9fW4tEtgEOtQ29cTpIBm47Ey4LCX'//百度地图密钥
});
const app = createApp(App)
const app = createApp(App);
app.use(createPinia())
app.use(router)
app.use(router).use(store);
app.use(i18n);
app.mount('#app');
app.mount('#app')

View File

@ -1,42 +1,31 @@
import { createRouter, createWebHistory, Router, RouteRecordRaw } from 'vue-router';
import NProgress from 'nprogress';
import exceptionRoutes from '@/router/route.exception';
import asyncRoutes from '@/router/route.async';
import commonRoutes from '@/router/route.common';
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import test from './module/test'
import myInfo from './module/myInfo'
const routes: Array<RouteRecordRaw> = [
// 无鉴权的业务路由 ex:登录
...commonRoutes,
// 带鉴权的业务路由
...asyncRoutes,
// 异常页必须放在路由匹配规则的最后
...exceptionRoutes,
];
{
path: '/echarts',
name: 'echartsScreen',
meta: {
title: '',
icon: '',
},
component: () => import('views/echarts/index.vue'),
},
{
path: '/screen/sharePlatform',
name: 'sharePlatform',
meta: {
title: '',
icon: '',
},
component: () => import('views/screen/sharePlatform.vue'),
},
]
const router: Router = createRouter({
// 新的vue-router4 使用 history路由模式 和 base前缀
history: createWebHistory(import.meta.env.VITE_BASE),
routes,
});
const router = createRouter({
// 路由模式
history: createWebHashHistory(),
routes
})
/**
* @description: resolve
* @param {RouteLocationNormalized} to
* @param {RouteLocationNormalizedLoaded} from
* @return {*}
*/
router.beforeEach((to, from) => {
console.log('全局路由前置守卫to,from\n', to, from);
// 设置页面标题
document.title = (to.meta.title as string) || import.meta.env.VITE_APP_TITLE;
if (!NProgress.isStarted()) {
NProgress.start();
}
});
router.afterEach((to, from) => {
console.log('全局路由后置守卫to,from\n', to, from);
NProgress.done();
});
export default router;
export default router

View File

@ -0,0 +1,12 @@
export default [
{
path: 'userInfo', // 主路由地址
name: 'userInfo',
component: () => import('views/myInfo/userInfo/UserIndex.vue'), // 组件加载
meta: {
title: '个人信息',
keepAlive: true,
AuthFlag: false
}
}
]

42
src/router/module/test.ts Normal file
View File

@ -0,0 +1,42 @@
export default [
{
path: 'piniaTest', //
name: 'piniaTest',
component: () => import('views/test/PiniaTest.vue'), // 组件加载
meta: {
title: 'pinia测试',
keepAlive: true,
AuthFlag: false
}
},
{
path: 'routerTest', //
name: 'routerTest',
component: () => import('views/test/RouterTest.vue'), // 组件加载
meta: {
title: '路由测试',
keepAlive: true,
AuthFlag: false
}
},
{
path: 'timeTest', //
name: 'timeTest',
component: () => import('views/test/TimeTest.vue'), // 组件加载
meta: {
title: '时间测试',
keepAlive: true,
AuthFlag: false
}
},
{
path: 'mittTest', //
name: 'mittTest',
component: () => import('views/test/MittTest.vue'), // 组件加载
meta: {
title: '全局事件测试',
keepAlive: true,
AuthFlag: false
}
}
]

View File

@ -1,48 +0,0 @@
// 需要鉴权的业务路由
import { RouteRecordRaw } from 'vue-router';
const asyncRoutes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'home',
meta: {
title: '',
icon: '',
},
component: () => import('@/views/home/index.vue'),
},
{
path: '/process',
name: 'process',
meta: {
title: 'Template configuration process',
icon: '',
},
component: () => import('@/views/example/MarkdownPage.vue'),
},
{
path: '/echarts',
name: 'echartsScreen',
meta: {
title: '',
icon: '',
},
component: () => import('@/views/echarts/index.vue'),
},
{
path: '/screen/sharePlatform',
name: 'sharePlatform',
meta: {
title: '',
icon: '',
},
component: () => import('@/views/screen/sharePlatform.vue'),
},
];
export default asyncRoutes;

View File

@ -1,6 +0,0 @@
// 不需要鉴权的业务路由
import { RouteRecordRaw } from 'vue-router';
const commonRoutes: Array<RouteRecordRaw> = [];
export default commonRoutes;

View File

@ -1,28 +0,0 @@
// 跟鉴权无关的特殊路由
import { RouteRecordRaw } from 'vue-router';
const exceptionRoutes: Array<RouteRecordRaw> = [
{
path: '/401',
name: '401',
meta: {
title: '需要登录',
},
component: () => import('@/views/exception/401.vue'),
},
{
path: '/404',
name: '404',
meta: {
title: '非常抱歉,页面走丢了',
},
component: () => import('@/views/exception/404.vue'),
},
{
path: '/:pathMatch(.*)',
meta: {},
redirect: '/404',
},
];
export default exceptionRoutes;

View File

@ -1,5 +1,6 @@
import { createPinia } from 'pinia';
import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
const pinia = createPinia()
pinia.use(piniaPluginPersist) // 相当于vuex持久化存储
const store = createPinia();
export default store;
export default pinia

32
src/store/main.ts Normal file
View File

@ -0,0 +1,32 @@
export const useStore = defineStore('main', {
state: () => {
return {
loadingFlag: false, //loading控制,
token: ''
}
},
getters: {},
actions: {
showLoading() {
this.loadingFlag = true
},
hideLoading() {
this.loadingFlag = false
},
setToken(val: any) {
this.token = val
}
},
persist: {
enabled: true, // 开启数据缓存
strategies: [
{
// 自定义存储的 key默认是 store.$id
key: 'main',
storage: localStorage, //缓存模式 可选 localStorage sessionStorage
// state 中的字段名,按组打包储存
paths: ['text', 'age'] //需要缓存的字段 与 state中相关联
}
]
}
})

30
src/store/myInfo.ts Normal file
View File

@ -0,0 +1,30 @@
export const useStore = defineStore('myInfo', {
state: () => {
return {
userName: '99'
}
},
getters: {
textConbain: (state) => state.userName + '4444',
textEnd() {
return this.textConbain + '666'
}
},
actions: {
updateText() {
console.log('updateText')
}
},
persist: {
enabled: true, // 开启数据缓存
strategies: [
{
// 自定义存储的 key默认是 store.$id
key: 'userName',
storage: localStorage, //缓存模式 可选 localStorage sessionStorage
// state 中的字段名,按组打包储存
paths: ['userName'] //需要缓存的字段 与 state中相关联
}
]
}
})

View File

@ -1,26 +0,0 @@
import { defineStore } from 'pinia';
const theme = defineStore({
// 这里的id必须为唯一ID
id: 'theme',
state: () => {
return {
themeType: '亮蓝色',
themeColor: '#2080F0FF',
};
},
// 等同于vuex的getter
getters: {
getThemeType: (state) => state.themeType,
getThemeColor: (state) => state.themeColor,
},
// pinia 放弃了 mutations 只使用 actions
actions: {
// actions可以用async做成异步形式
setThemeType(type: string) {
this.themeType = type;
},
},
});
export default theme;

48
src/style/css/reset.css Normal file
View File

@ -0,0 +1,48 @@
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
#app {
width: 100vw;
height: 100vh;
}

View File

@ -0,0 +1,5 @@
.button {
border-radius: 3px;
background-color: green;
color: white;
}

62
src/style/scss/mixin.scss Normal file
View File

@ -0,0 +1,62 @@
@mixin fontStyle($size, $color, $weight, $lineH, $align) {
/*
$size 字体大小
$color 文字颜色
$weight 字体加粗
$lineH 行高
$align 对齐方式
*/
font-size: $size;
color: $color;
font-weight: $weight;
line-height: $lineH;
text-align: $align;
}
@mixin flexStyle($js, $al, $dir, $wrap) {
/* $js justify-content
$al align-items
$dir flex-direction
$wrap flex-wrap */
display: flex;
justify-content: $js;
align-items: $al;
flex-flow: $dir $wrap;
}
@mixin text-elli {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
@mixin text-elli-muti($row) {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: $row;
-webkit-box-orient: vertical;
}
@mixin place($size, $color) {
::-webkit-input-placeholder {
font-size: $size;
color: $color;
}
}
@mixin overSc($h) {
height: $h;
overflow: auto;
}
@mixin wh($w, $h) {
width: $w;
height: $h;
}
@mixin fixedPoupu() {
position: fixed;
inset: 0;
background-color: rgba($color: #000, $alpha: 30%);
}

View File

@ -0,0 +1,4 @@
.van-button--primary {
background-color: $main-color;
border: $main-color;
}

View File

@ -0,0 +1,2 @@
$main-color: #22b2ff;
$second-color: #666;

View File

8
src/utils/bus.ts Normal file
View File

@ -0,0 +1,8 @@
import mitt, { Emitter } from 'mitt'
/* eslint-disable @typescript-eslint/no-explicit-any */
type Events = {
[propName: string]: any
}
const mittBus: Emitter<Events> = mitt<Events>()
export default mittBus

View File

@ -1,2 +0,0 @@
export const isDark = useDark();
export const toggleDark = useToggle(isDark);

80
src/utils/dom.ts Normal file
View File

@ -0,0 +1,80 @@
import { unref, Ref } from 'vue'
import { isIOS } from './validate'
export type ScrollElement = Element | Window
// 获取元素 滚动出去的高度
export function getScrollTop(el: ScrollElement): number {
const top = 'scrollTop' in el ? el.scrollTop : el.pageYOffset
// iOS scroll bounce cause minus scrollTop
return Math.max(top, 0)
}
// 设置元素滚动出去的距离
export function setScrollTop(el: ScrollElement, value: number) {
if ('scrollTop' in el) {
el.scrollTop = value
} else {
el.scrollTo(el.scrollX, value)
}
}
// 获取根元素 滚动出去的高度
export function getRootScrollTop(): number {
return (
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop ||
0
)
}
// 设置根元素滚动出去的距离
export function setRootScrollTop(value: number) {
setScrollTop(window, value)
setScrollTop(document.body, value)
}
// hack for iOS12 page scroll
// see: https://developers.weixin.qq.com/community/develop/doc/00044ae90742f8c82fb78fcae56800
export function resetScroll() {
if (isIOS) {
setRootScrollTop(getRootScrollTop())
}
}
// 阻止事件冒泡
export const stopPropagation = (event: Event) => event.stopPropagation()
// 阻止默认行为
export function preventDefault(event: Event, isStopPropagation?: boolean) {
/* istanbul ignore else */
if (typeof event.cancelable !== 'boolean' || event.cancelable) {
event.preventDefault()
}
if (isStopPropagation) {
stopPropagation(event)
}
}
// 判断元素是否隐藏
export function isHidden(
elementRef: HTMLElement | Ref<HTMLElement | undefined>
) {
const el = unref(elementRef)
if (!el) {
return false
}
const style = window.getComputedStyle(el)
const hidden = style.display === 'none'
// offsetParent returns null in the following situations:
// 1. The element or its parent element has the display property set to none.
// 2. The element has the position property set to fixed
const parentHidden = el.offsetParent === null && style.position !== 'fixed'
return hidden || parentHidden
}

View File

@ -1,12 +0,0 @@
export const fontChart=(res:any)=> {
let docEl = document.documentElement,
clientWidth =
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;
if (!clientWidth) return;
// 此处的3840 为设计稿的宽度,记得修改!
let fontSize = clientWidth / 1920;
return res * fontSize;
}

View File

@ -1,19 +0,0 @@
export declare interface instanceObject {
[key: string]: string;
}
/**
* JSON转url参数
* @param data Json格式数据
* */
export const formatJsonToUrlParams = (data: instanceObject) => {
return typeof data === 'object'
? Object.keys(data)
.map((key) => {
return `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`;
})
.join('&')
: '';
};
export default formatJsonToUrlParams;

View File

@ -1,3 +1,72 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
// 深拷贝
export function deepMerge(...objs: any[]): any {
const result = Object.create(null)
objs.forEach((obj) => {
if (obj) {
Object.keys(obj).forEach((key) => {
const val = obj[key]
if (isPlainObject(val)) {
// 递归
if (isPlainObject(result[key])) {
result[key] = deepMerge(result[key], val)
} else {
result[key] = deepMerge(val)
}
} else {
result[key] = val
}
})
}
})
return result
}
export const isPlainObject = (val: any) =>
!!val && typeof val === 'object' && val.constructor === Object
//防抖
// fn 要执行的函数
// delay 执行函数
export const debounce = <T extends (...args: any[]) => ReturnType<T>>(
callback: T,
timeout: number
): ((...args: Parameters<T>) => void) => {
let timer: ReturnType<typeof setTimeout>
return (...args: Parameters<T>) => {
clearTimeout(timer)
timer = setTimeout(() => {
callback(...args)
}, timeout)
}
}
//封装节流
// fn 要执行的函数
// delay 执行函数
export const throttle = <T extends (...args: any[]) => ReturnType<T>>(
callback: T,
timeout: number
): ((...args: Parameters<T>) => void) => {
let valid = true
let timer: ReturnType<typeof setTimeout>
return (...args: Parameters<T>) => {
if (!valid) {
return false
}
valid = false
clearTimeout(timer)
timer = setTimeout(() => {
callback(...args)
valid = true
}, timeout)
}
}
export const getImg = (imgUrl:string) => {
return new URL(imgUrl, import.meta.url).href;
}

19
src/utils/query.ts Normal file
View File

@ -0,0 +1,19 @@
// 获取地址栏参数
export function GetUrlParameter(parameterName: string) {
const url = document.location.toString()
console.log(url)
const arrObj = url.split('?')
if (arrObj.length > 1) {
const arrPara = arrObj[1].split('&')
let arr
for (let i = 0; i < arrPara.length; i++) {
arr = arrPara[i].split('=')
if (arr != null && arr[0] === parameterName) {
return arr[1].replace('#', '').replace('/', '')
}
}
return ''
} else {
return ''
}
}

119
src/utils/time.ts Normal file
View File

@ -0,0 +1,119 @@
import moment from 'moment'
/* eslint-disable @typescript-eslint/no-explicit-any */
/*
https://blog.csdn.net/qq_36228377/article/details/125196997
*/
export function formatTime(curTime: string, formatVal: string) {
/*
curTIme:要格式化的时间
formatVal:格式化时间的格式
*/
// 例如 curTime 2021-02-03 12-21-22 formatVal YYYY年MM月DD日 HH时mm分ss秒
return moment(curTime).format(formatVal)
}
// 时间格式
/* M 112
MM 0112
MMM Jan到Dec
MMMM January到December
Q 14
D 131
DD 0131
d 0606
ddd Sun到Sat
dddd Sunday到Saturday
w 4242
YYYY 2014 2000
YY 14 98
A AM PM AM PM
a am pm am pm
HH 24 0023
H 24 023
hh 12 0012
h 12 012
m 059
mm 0059
s 159
ss 0159
X Unix时间戳 1411572969 */
export function getDiffTime(start: string, end: string, unit: any) {
/*
start
end
unit
*/
moment(start).diff(moment(end), unit) //32
}
/**
*
* timestamp
*/
export function formatDate(timestamp: any) {
// 补全为13位
const arrTimestamp: any = (timestamp + '').split('')
for (let start = 0; start < 13; start++) {
if (!arrTimestamp[start]) {
arrTimestamp[start] = '0'
}
}
timestamp = arrTimestamp.join('') * 1
const minute = 1000 * 60
const hour = minute * 60
const day = hour * 24
const month = day * 30
const now = new Date().getTime()
const diffValue = now - timestamp
// 如果本地时间反而小于变量时间
if (diffValue < 0) {
return '不久前'
}
// 计算差异时间的量级
const monthC: any = diffValue / month
const weekC: any = diffValue / (7 * day)
const dayC: any = diffValue / day
const hourC: any = diffValue / hour
const minC: any = diffValue / minute
// 数值补0方法
const zero = function (value: number) {
if (value < 10) {
return '0' + value
}
return value
}
// 使用
if (monthC > 4) {
// 超过1年直接显示年月日
return (function () {
const date = new Date(timestamp)
return (
date.getFullYear() +
'年' +
zero(date.getMonth() + 1) +
'月' +
zero(date.getDate()) +
'日'
)
})()
} else if (monthC >= 1) {
return parseInt(monthC) + '月前'
} else if (weekC >= 1) {
return parseInt(weekC) + '周前'
} else if (dayC >= 1) {
return parseInt(dayC) + '天前'
} else if (hourC >= 1) {
return parseInt(hourC) + '小时前'
} else if (minC >= 1) {
return parseInt(minC) + '分钟前'
}
return '刚刚'
}

50
src/utils/validate.ts Normal file
View File

@ -0,0 +1,50 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
// 是否在浏览器
export const inBrowser = typeof window !== 'undefined'
// 数值或者字符串
export type Numeric = number | string
//是否定义
export const isDef = <T>(val: T): val is NonNullable<T> =>
val !== undefined && val !== null
// eslint-disable-next-line @typescript-eslint/ban-types
// 是否是函数
export const isFunction = (val: unknown) => typeof val === 'function'
// 是否是对象
export const isObject = (val: unknown): val is Record<any, any> =>
val !== null && typeof val === 'object'
// 是否是promise
export const isPromise = <T = any>(val: unknown): val is Promise<T> =>
isObject(val) && isFunction(val.then) && isFunction(val.catch)
// 是否是日期
export const isDate = (val: unknown): val is Date =>
Object.prototype.toString.call(val) === '[object Date]' &&
!Number.isNaN((val as Date).getTime())
// 是否是电话
export function isMobile(value: string): boolean {
value = value.replace(/[^-|\d]/g, '')
return (
/^((\+86)|(86))?(1)\d{10}$/.test(value) ||
/^0[0-9-]{10,13}$/.test(value)
)
}
// 能否转换成数值类型
export const isNumeric = (val: Numeric): val is string =>
typeof val === 'number' || /^\d+(\.\d+)?$/.test(val)
// 是不是 ios 环境
export const isIOS = inBrowser
? /ios|iphone|ipad|ipod/.test(navigator.userAgent.toLowerCase())
: false
export const isAndroid = inBrowser
? /android|linux/.test(navigator.userAgent.toLowerCase())
: false

15
src/views/AboutView.vue Normal file
View File

@ -0,0 +1,15 @@
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
<style>
@media (min-width: 1024px) {
.about {
min-height: 100vh;
display: flex;
align-items: center;
}
}
</style>

9
src/views/HomeView.vue Normal file
View File

@ -0,0 +1,9 @@
<script setup lang="ts">
import TheWelcome from '../components/TheWelcome.vue'
</script>
<template>
<main>
<TheWelcome />
</main>
</template>

56
src/views/Index.vue Normal file
View File

@ -0,0 +1,56 @@
<template>
<div>
<div
class="pathItem"
v-for="(item, index) in routeList.list"
:key="index"
@click="toPage(item)"
>
{{ item.name }}
</div>
</div>
</template>
<script setup lang="ts">
const router = useRouter()
const routeList = reactive({
list: [
{
name: 'vant-scss演示',
path: 'vantTest'
},
{
name: '时间测试',
path: 'timeTest'
},
{
name: '全局事件 mitt 演示',
path: 'mittTest'
},
{
name: 'pinia演示',
path: 'piniaTest'
},
{
name: '路由演示',
path: 'piniaTest'
}
]
})
/* eslint-disable @typescript-eslint/no-explicit-any */
const toPage = (item: any) => {
router.push({ name: item.path })
}
</script>
<style scoped lang="scss">
// @mixin fontStyle($size,$color,$weight,$lineH,$align) {
// @mixin flexStyle($js,$al,$dir,$wrap){
.pathItem {
@include fontStyle(48px, green, bold, 80px, center);
@include wh(750px, 80px);
margin-bottom: 12px;
}
</style>

View File

@ -1,8 +0,0 @@
<template>
<EnProcess v-if="locale === 'en'"></EnProcess>
<ZhProcess v-else></ZhProcess>
</template>
<script setup lang="ts">
const { locale } = useI18n();
</script>

View File

@ -1,20 +0,0 @@
<template>
<el-row>
<el-col>
<el-result icon="warning" title="页面无权限" sub-title="请联系管理员申请权限">
<template #extra>
<el-button type="primary" @click="goBack">Back</el-button>
</template>
</el-result>
</el-col>
</el-row>
</template>
<script setup lang="ts">
const router = useRouter();
const goBack = () => {
router.push({
name: 'home',
});
};
</script>

View File

@ -1,20 +0,0 @@
<template>
<el-row>
<el-col>
<el-result icon="warning" title="页面未找到" sub-title="请检查路径后重试或返回首页">
<template #extra>
<el-button type="primary" @click="goBack">Back</el-button>
</template>
</el-result>
</el-col>
</el-row>
</template>
<script setup lang="ts">
const router = useRouter();
const goBack = () => {
router.push({
name: 'home',
});
};
</script>

View File

@ -1,5 +0,0 @@
<template></template>
<script setup lang="ts"></script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,26 @@
<template>
<router-view></router-view>
</template>
<script lang="ts" setup>
onBeforeMount(() => {
console.log('onBeforeMount')
})
onMounted(() => {
console.log('onMounted')
})
onBeforeUnmount(() => {
console.log('onBeforeUnmount')
})
onUnmounted(() => {
console.log('onUnmounted')
})
let a = computed(() => {
return 'aaa'
})
console.log(a)
</script>
<style scoped></style>

View File

@ -0,0 +1,26 @@
<template>
<h1>我的</h1>
</template>
<script lang="ts" setup>
onBeforeMount(() => {
console.log('onBeforeMount')
})
onMounted(() => {
console.log('onMounted')
})
onBeforeUnmount(() => {
console.log('onBeforeUnmount')
})
onUnmounted(() => {
console.log('onUnmounted')
})
let a = computed(() => {
return 'aaa'
})
console.log(a)
</script>
<style scoped></style>

View File

@ -1,7 +0,0 @@
<template></template>
<script setup lang="ts">
</script>
<style lang="scss" scoped></style>

9
src/views/test/Index.vue Normal file
View File

@ -0,0 +1,9 @@
<template>
<div>
<router-view></router-view>
</div>
</template>
<script setup lang="ts"></script>
<style scoped></style>

View File

@ -0,0 +1,33 @@
<template>
<button @click="testFn">全局事件测试</button>
</template>
<script lang="ts" setup>
import bus from 'utils/bus'
onBeforeMount(() => {
console.log('onBeforeMount')
})
onMounted(() => {
console.log('onMounted')
})
onBeforeUnmount(() => {
console.log('onBeforeUnmount')
})
onUnmounted(() => {
console.log('onUnmounted')
})
let a = computed(() => {
return 'aaa'
})
console.log(a)
const testFn = () => {
console.log('测试')
bus.emit('sendMsg', '666')
}
</script>
<style scoped></style>

View File

@ -0,0 +1,31 @@
<template>
<div class="test">
<h1>测试--</h1>
<!-- {{ mainStore.text }} -->
</div>
<button @click="changeTextFn">修改</button>
</template>
<script lang="ts" setup>
// import { useStore } from 'store/main'
// const mainStore = useStore()
// mainStore.text
const changeTextFn = () => {
// mainStore.text="999"
// mainStore.$patch((state)=>{
// state.text = ""
// })
//
// mainStore.$patch({
// text: '55555555'
// })
}
let a = '6666'
console.log(a)
</script>
<style scoped lang="scss">
.test {
color: $main-color;
}
</style>

View File

@ -0,0 +1,32 @@
<template>
<h1>路由</h1>
<button @click="toPage">路由测试</button>
</template>
<script lang="ts" setup>
const router = useRouter()
onBeforeMount(() => {
console.log('onBeforeMount')
})
onMounted(() => {
console.log('onMounted')
})
onBeforeUnmount(() => {
console.log('onBeforeUnmount')
})
onUnmounted(() => {
console.log('onUnmounted')
})
let a = computed(() => {
return 'aaa'
})
console.log(a)
const toPage = () => {
router.push({ name: 'piniaTest' })
}
</script>
<style scoped></style>

View File

@ -0,0 +1,49 @@
<template>
<h1>我是时间测试</h1>
<van-button type="primary" @click="toastFn">6666</van-button>
</template>
<script lang="ts" setup>
/* eslint-disable @typescript-eslint/no-explicit-any */
import moment from 'moment'
import bus from 'utils/bus'
const { proxy } = getCurrentInstance() as any
onBeforeMount(() => {
console.log('onBeforeMount')
})
onMounted(() => {
bus.on('sendMsg', getMsg)
console.log('63666', moment().format('YYYY年MM月DD日'))
let currentTime = moment('2019-02-03 12:24:36').format(
'YYYY年MM月DD日 HH时mm分ss秒'
)
console.log('currentTime', currentTime)
let diff = moment('2020-08-09').diff(moment('2020-07-08'), 'days')
console.log(diff)
let firstTime = moment().startOf('month').format('YYYY-MM-DD')
console.log('firstTime', firstTime)
})
onBeforeUnmount(() => {
console.log('onBeforeUnmount')
})
onUnmounted(() => {
console.log('onUnmounted')
})
let a = computed(() => {
return 'aaa'
})
console.log(a)
const getMsg = (val: string) => {
console.log('val', val)
}
const toastFn = () => {
proxy.$toast('6666')
}
</script>
<style scoped></style>

View File

@ -1,101 +0,0 @@
# 施工单位自有设备详情
```js
data: [
{
title:"广西电网",
count:'12'
},
{
title:"广西电网",
count:'12'
}
]
```
# 机手人数
```js
data: [
[
{
title:"广西电网",
count:'12'
},
{
title:"广西电网",
count:'12'
}
]
```
# 租赁订单月统计
```js
data: [
[
{
title:"广西电网",
count:'12'
},
{
title:"广西电网",
count:'12'
}
]
```
# 租赁在用装备排名
```js
data: [
[
{
title:"广西电网",
count:'12'
},
{
title:"广西电网",
count:'12'
}
]
```
# 设备租赁分布图
```js
data: [
{
type:"自有",//类型 自有 待租 在租
lng:'经度'
lat:'纬度',
selfCount: 256,//自有 数量
toCount: 2456,//待租数量
inCount: 745,//在租数量
}
]
```
# 装备信息
<!-- 地图列表 -->
```js
data: [
{
lng:'经度'
lat:'纬度',
},
{
lng:'经度'
lat:'纬度',
},
{
lng:'经度'
lat:'纬度',
},
]
```

12
tsconfig.app.json Normal file
View File

@ -0,0 +1,12 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"composite": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}

View File

@ -1,24 +1,37 @@
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"types": ["@intlify/vite-plugin-vue-i18n/client"],
// baseUrl baseUrl
"baseUrl": ".",
//
"paths": {
"@/*": ["src/*"],
}
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"jsx": "preserve",
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"lib": ["ESNext", "DOM"],
"skipLibCheck": true,
"noEmit": true,
"baseUrl": "./",
"paths": {
"@": ["src/*"],
"assets/*": ["src/assets/"],
"components/*": ["src/components/*"],
"store/*": ["src/store/*"],
"views/*": ["src/views/*"],
"router/*": ["src/router/*"],
"utils/*": ["src/utils/*"],
"http/*": ["src/http/*"]
},
"types": ["pinia-plugin-persist","vite/client"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
//
"exclude": ["node_modules"]
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"types/**/*.d.ts",
"generated/**/*.d.ts"
],
"references": [{ "path": "./tsconfig.node.json" }]
}

16
tsconfig.node.json Normal file
View File

@ -0,0 +1,16 @@
{
"extends": "@tsconfig/node18/tsconfig.json",
"include": [
"vite.config.*",
"vitest.config.*",
"cypress.config.*",
"nightwatch.conf.*",
"playwright.config.*"
],
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["node"]
}
}

View File

@ -1,64 +1,156 @@
import { defineConfig, loadEnv } from 'vite';
import { resolve } from 'path';
import presets from './presets/presets';
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
// https://vitejs.dev/config/
export default defineConfig((env) => {
// env 环境变量
const viteEnv = loadEnv(env.mode, process.cwd());
import { resolve } from 'path'
import vueJsx from '@vitejs/plugin-vue-jsx'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { createHtmlPlugin } from 'vite-plugin-html'
import moment from 'moment'
import { env } from 'node:process'
return {
base: viteEnv.VITE_BASE,
// 插件
plugins: [presets(env)],
// 别名设置
// @ts-ignore
import pjson from './package.json'
const now = new Date()
export default ({ mode }: any) => {
const envInfo = loadEnv(mode, process.cwd() + '/env')
const isProduction = mode == 'production' //正式生产环境
const isSIT = ['sit', 'dev', 'development'].includes(mode)
const isUAT = ['uat'].includes(mode)
function getTestResource(): string {
if (isSIT) {
return `https://testSit.com`
} else if (isUAT) {
return `https://testUat.com`
} else if (mode === 'production') {
return `https://production.com`
}
return ''
}
return defineConfig({
base: './',
plugins: [
vue(),
vueJsx(),
AutoImport({
imports: ['vue', 'vue-router', 'pinia'],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
createHtmlPlugin({
inject: {
data: {
injectTestResource: getTestResource()
// 动态插入js脚本
}
}
}),
// 打包文件
],
resolve: {
// 路径别名配置
alias: {
'@': resolve(__dirname, './src'), // 把 @ 指向到 src 目录去
},
},
// 服务设置
server: {
host: true, // host设置为true才可以使用network的形式以ip访问项目
port: 8080, // 端口号
open: true, // 自动打开浏览器
cors: true, // 跨域设置允许
strictPort: true, // 如果端口已占用直接退出
// 接口代理
proxy: {
'/api': {
// 本地 8000 前端代码的接口 代理到 8888 的服务端口
target: 'http://localhost:8888/',
changeOrigin: true, // 允许跨域
rewrite: (path) => path.replace('/api/', '/'),
},
},
},
build: {
reportCompressedSize: false,
// 消除打包大小超过500kb警告
chunkSizeWarningLimit: 2000,
minify: 'esbuild',
assetsDir: 'static/assets',
// 静态资源打包到dist下的不同目录
rollupOptions: {
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
},
},
'@': resolve(__dirname, './src'),
assets: resolve(__dirname, './src/assets'),
components: resolve(__dirname, './src/components'),
store: resolve(__dirname, './src/store'),
views: resolve(__dirname, './src/views'),
router: resolve(__dirname, './src/router'),
utils: resolve(__dirname, './src/utils'),
http: resolve(__dirname, './src/http')
}
},
css: {
preprocessorOptions: {
// 全局引入了 scss 的文件
scss: {
additionalData: `
@import "@/assets/styles/variables.scss";
`,
javascriptEnabled: true,
},
},
// 两种方式都可以
additionalData:
"@import '@/style/scss/variable.scss';@import '@/style/scss/mixin.scss';@import '@/style/scss/vantReset.scss';"
}
}
},
};
});
server: {
host: '0.0.0.0',
// port: Number(envInfo.VITE_PORT),
// open: envInfo.VITE_OPEN,
proxy: {
'/proxyApi': {
target: 'https://test.com',
secure: false,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/proxyApi/, ''),
configure: (proxy, _options) => {
proxy.on('error', (err, _req, _res) => {
console.log('proxy error', err)
})
proxy.on('start', (req, res, target) => {
console.log(
'Proxy Start:',
req.method,
req.url,
req.headers,
_options
)
})
proxy.on('proxyReq', (proxyReq, req, _res) => {
console.log(
'Sending Request to the Target:',
req.method,
req.url,
req.headers,
_options
)
proxyReq.removeHeader('origin')
// 跨域解决
})
proxy.on('proxyRes', (proxyRes, req, _res) => {
console.log(
'Received Response from the Target:',
proxyRes.statusCode,
proxyRes.headers,
req.url
)
})
}
}
},
hmr: {
overlay: true
}
},
envDir: 'env',
build: {
outDir: 'dist/' + pjson.name,
emptyOutDir: true,
terserOptions: {
compress: {
drop_console: isProduction, //生产正式 去除
drop_debugger: isProduction //生产正式 去除
}
}
/*
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
return id
.toString()
.split('node_modules/')[1]
.split('/')[0]
.toString()
}
}
}
}
*/
}
})
}

View File

@ -1,43 +0,0 @@
import { defineConfig } from 'vite-plugin-windicss';
import typography from 'windicss/plugin/typography';
import colors from 'windicss/colors';
export default defineConfig({
darkMode: 'class',
plugins: [typography()],
theme: {
fontFamily: {
sans: ['Open Sans', 'ui-sans-serif', 'system-ui'],
serif: ['Montserrat', 'ui-serif', 'Georgia'],
mono: ['Fira Sans', 'ui-monospace', 'SFMono-Regular'],
},
extend: {
typography: {
DEFAULT: {
css: {
maxWidth: '65ch',
color: 'inherit',
a: {
color: 'inherit',
opacity: 0.75,
fontWeight: '500',
textDecoration: 'underline',
'&:hover': {
opacity: 1,
color: colors.teal[600],
},
},
b: { color: 'inherit' },
strong: { color: 'inherit' },
em: { color: 'inherit' },
h1: { color: 'inherit' },
h2: { color: 'inherit' },
h3: { color: 'inherit' },
h4: { color: 'inherit' },
code: { color: 'inherit' },
},
},
},
},
},
});