项目初始化

This commit is contained in:
13218645326 2023-12-02 11:33:44 +08:00
commit d60cd038ba
55 changed files with 4885 additions and 0 deletions

28
.gitignore vendored Normal file
View File

@ -0,0 +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?

3
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
}

40
README.md Normal file
View File

@ -0,0 +1,40 @@
# vue3PcTemplate
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[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).
## Type Support for `.vue` Imports in TS
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.
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:
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.
## Customize configuration
See [Vite Configuration Reference](https://vitejs.dev/config/).
## Project Setup
```sh
npm install
```
### Compile and Hot-Reload for Development
```sh
npm run dev
```
### Type-Check, Compile and Minify for Production
```sh
npm run build
```

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')
}

14
components.d.ts vendored Normal file
View File

@ -0,0 +1,14 @@
/* 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 {
ElButton: typeof import('element-plus/es')['ElButton']
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')
}

13
index.html Normal file
View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<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>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

43
package.json Normal file
View File

@ -0,0 +1,43 @@
{
"name": "vue3pctemplate",
"version": "0.0.0",
"private": true,
"scripts": {
"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",
"build-only": "vite build",
"type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false"
},
"dependencies": {
"@vueuse/core": "^10.6.1",
"axios": "^1.6.2",
"element-plus": "^2.4.3",
"mitt": "^3.0.1",
"moment": "^2.29.4",
"nprogress": "^0.2.0",
"pinia": "^2.1.7",
"pinia-plugin-persist": "^1.0.0",
"vite-plugin-html": "^3.2.0",
"vite-plugin-zip-file": "^2.2.0",
"vue": "^3.3.4",
"vue-router": "^4.2.5"
},
"devDependencies": {
"@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"
}
}

3091
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

8
src/App.vue Normal file
View File

@ -0,0 +1,8 @@
<template>
<el-button type="primary">424242 </el-button>
<RouterView />
</template>
<script setup lang="ts">
</script>
<style scoped></style>

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

35
src/assets/main.css Normal file
View File

@ -0,0 +1,35 @@
@import './base.css';
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
font-weight: normal;
}
a,
.green {
text-decoration: none;
color: hsla(160, 100%, 37%, 1);
transition: 0.4s;
}
@media (hover: hover) {
a:hover {
background-color: hsla(160, 100%, 37%, 0.2);
}
}
@media (min-width: 1024px) {
body {
display: flex;
place-items: center;
}
#app {
display: grid;
grid-template-columns: 1fr 1fr;
padding: 0 2rem;
}
}

5
src/http/api/myInfo.ts Normal file
View File

@ -0,0 +1,5 @@
import { post } from '../index'
export function apiTest() {
return post('/userms/ut/userCardInfo/getCardInfo/v1', {})
}

122
src/http/index.ts Normal file
View File

@ -0,0 +1,122 @@
//http.ts
/* eslint-disable @typescript-eslint/no-explicit-any */
import axios from 'axios'
import NProgress from 'nprogress'
import { useStore } from 'store/main'
const store = useStore()
// const CancelToken = axios.CancelToken
// const source = CancelToken.source()
const baseUrl = import.meta.env.VITE_API_URL
// const mode = import.meta.env.VITE_BUILD_MODE
const service = axios.create({
baseURL: baseUrl,
timeout: 60000
})
service.interceptors.request.use(
(config) => {
return config
},
(error) => {
return error
}
)
// 响应拦截
service.interceptors.response.use(
(res) => {
return res.data
},
(error) => {
console.log('error-异常', error)
}
)
export function get(url: string, params: any) {
return new Promise((resolve, reject) => {
NProgress.start()
service
.get(url, { params })
.then((res: any) => {
NProgress.done()
if (res.code == '0000') {
resolve(res.data)
} else {
reject(res.data)
}
})
.catch((err) => {
NProgress.done()
reject(err.data)
})
})
}
export function post(url: string, params: any) {
return new Promise((resolve, reject) => {
NProgress.start()
service
.post(url, params, {
headers: { 'Content-Type': 'application/json; charset=utf-8' }
})
.then((res: any) => {
NProgress.done()
console.log('---------------------------', res)
if (res.code == '0000') {
resolve(res.data)
} else {
reject(res)
}
})
.catch((err) => {
NProgress.done()
reject(err)
})
})
}
export function upload(url: string, params: any) {
const formData = new FormData()
for (const key in params) {
if (Object.prototype.hasOwnProperty.call(params, key)) {
formData.append(key, params[key])
}
}
return new Promise((resolve, reject) => {
NProgress.start()
service
.post(url, formData, {
headers: { 'Content-Type': 'multipart/form-data' }
})
.then((res: any) => {
NProgress.done()
if (res.code == '0000') {
resolve(res.data)
} else {
reject(res.data)
}
})
.catch((err) => {
NProgress.done()
reject(err.data)
})
})
}
export function download(url: string, params: any) {
return new Promise((resolve, reject) => {
NProgress.start()
service
.post(url, params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
responseType: 'blob'
})
.then((res: any) => {
resolve(res)
})
.catch((err) => {
NProgress.done()
reject(err.data)
})
})
}

14
src/main.ts Normal file
View File

@ -0,0 +1,14 @@
import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.mount('#app')

45
src/router/index.ts Normal file
View File

@ -0,0 +1,45 @@
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import test from './module/test'
import myInfo from './module/myInfo'
const routes: Array<RouteRecordRaw> = [
{
path: '/index',
name: 'index',
component: () => import('views/Index.vue'),
meta: {
title: '目录页',
keepAlive: true,
AuthFlag: false
}
},
{
path: '/test', // 主路由地址
name: 'testIndex',
component: () => import('views/test/Index.vue'), // 组件加载
meta: {
title: '测试',
keepAlive: true,
AuthFlag: false
},
children: [...test]
},
{
path: '/myInfo', // 主路由地址
name: 'myInfo',
component: () => import('views/myInfo/Index.vue'), // 组件加载
meta: {
title: '我的',
keepAlive: true,
AuthFlag: false
},
children: [...myInfo]
}
]
const router = createRouter({
// 路由模式
history: createWebHashHistory(),
routes
})
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
}
}
]

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

@ -0,0 +1,43 @@
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
}
}
]
//

6
src/store/index.ts Normal file
View File

@ -0,0 +1,6 @@
import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
const pinia = createPinia()
pinia.use(piniaPluginPersist) // 相当于vuex持久化存储
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中相关联
}
]
}
})

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

@ -0,0 +1,9 @@
* {
margin: 0;
padding: 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: #f00;
$second-color: #666;

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

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
}

68
src/utils/index.ts Normal file
View File

@ -0,0 +1,68 @@
/* 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)
}
}

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

@ -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>

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>

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/*"]
}
}
}

37
tsconfig.json Normal file
View File

@ -0,0 +1,37 @@
{
"compilerOptions": {
"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",
"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"]
}
}

156
vite.config.ts Normal file
View File

@ -0,0 +1,156 @@
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
// https://vitejs.dev/config/
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'
// @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'),
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: {
// 两种方式都可以
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()
}
}
}
}
*/
}
})
}