提交 8fed849c authored 作者: 刘旭's avatar 刘旭

初次提交

上级
# 忽略public目录下文件的语法检查
public
# 忽略node_modules目录下文件的语法检查
node_modules
# 忽略src/assets目录下文件的语法检查
src/assets
# 忽略dist目录下文件的语法检查
dist
{
"globals": {
"Component": true,
"ComponentPublicInstance": true,
"ComputedRef": true,
"EffectScope": true,
"InjectionKey": true,
"PropType": true,
"Ref": true,
"VNode": 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
}
}
module.exports = {
env: {
browser: true,
es2021: true,
node: true
},
extends: [
'eslint:recommended', // 使用推荐的eslint
'plugin:vue/vue3-recommended', // 使用插件支持vue3
'plugin:prettier/recommended',
'eslint-config-prettier',
'./.eslintrc-auto-import.json'
],
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
parser: '@typescript-eslint/parser',
ecmaFeatures: {
modules: true,
jsx: true
}
},
plugins: [
'vue', // 引入vue的插件 eslint-plugin-vue
'prettier', // 引入规范插件 eslint-plugin-prettier
'@typescript-eslint'
],
globals: {},
// 这里时配置规则的,自己看情况配置
rules: {
// 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
//在rules中添加自定义规则
//关闭组件命名规则
'vue/multi-word-component-names': 'off',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'no-undef': 'off',
'no-console': 'off'
}
}
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
# .vscode/*
# !.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# Ignore artifacts:
build
coverage
# Ignore all HTML files:
*.html
**/.git
**/.svn
**/.hg
**/node_modules
\ No newline at end of file
{
"tabWidth": 2,
"semi": false,
"trailingComma": "none",
"singleQuote": true,
"printWidth": 100,
"arrowParens": "avoid",
"bracketSpacing": true,
"endOfLine": "auto",
"useTabs": false,
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"jsxBracketSameLine": false,
"rangeStart": 0,
"requirePragma": false,
"insertPragma": false,
"proseWrap": "preserve",
"htmlWhitespaceSensitivity": "css"
}
{
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
}
// 根目录下新建.vscode/settings.json文件
// settings.json
{
"editor.formatOnType": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}
下载 git clone xxxx
pnpm i 下载依赖
pnpm dev 运行项目
\ No newline at end of file
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vue3Web框架</title>
<style>
body,
html {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
{
"name": "vue3-web",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit --skipLibCheck && vite build",
"preview": "vite preview",
"lint": "eslint src --ext .vue,.js,.ts,.jsx,.tsx",
"lint:fix": "eslint src --ext .vue,.js,.ts,.jsx,.tsx --fix"
},
"dependencies": {
"@element-plus/icons-vue": "^2.1.0",
"@types/node": "^20.4.4",
"axios": "^1.4.0",
"element-plus": "^2.3.8",
"mockjs": "^1.1.0",
"pinia": "^2.1.4",
"pinia-plugin-persist": "^1.0.0",
"sass": "^1.64.1",
"vue": "^3.3.4",
"vue-router": "4"
},
"devDependencies": {
"@babel/core": "^7.22.9",
"@babel/eslint-parser": "^7.22.9",
"@typescript-eslint/eslint-plugin": "^6.1.0",
"@typescript-eslint/parser": "^6.1.0",
"@vitejs/plugin-vue": "^4.2.3",
"eslint": "^8.45.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-vue": "^9.15.1",
"prettier": "^3.0.0",
"terser": "^5.19.2",
"typescript": "^5.0.2",
"unplugin-auto-import": "^0.16.6",
"unplugin-vue-components": "^0.25.1",
"vite": "^4.4.5",
"vite-plugin-eslint": "^1.8.1",
"vite-plugin-mock": "2.9.6",
"vite-plugin-vue-setup-extend": "^0.4.0",
"vue-tsc": "^1.8.5"
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
\ No newline at end of file
<script setup lang="ts"></script>
<template>
<router-view></router-view>
</template>
<style scoped>
body {
height: 100%;
color: #333;
font:
1em/1.4 'Microsoft Yahei',
'PingFang SC',
'Avenir',
'Segoe UI',
'Hiragino Sans GB',
'STHeiti',
'Microsoft Sans Serif',
'WenQuanYi Micro Hei',
sans-serif;
}
</style>
<template>
<div class="footer-container">
<h1>Footer</h1>
</div>
</template>
<script setup lang="ts"></script>
<style lang="scss" scoped>
.footer-container {
margin: auto;
}
</style>
<template>
<div class="headers">
<div class="headers-top">
<div class="content">
<el-link :underline="false">登录</el-link>
<text class="slash"> / </text>
<el-link :underline="false">注册</el-link>
</div>
</div>
<div class="headers-bottom">
<div class="content">
<h1>西部人力培训中心</h1>
<el-link
v-for="(item, index) in tabsList"
:key="index"
class="item"
:underline="false"
href=""
target=""
>{{ item.name }}</el-link
>
<el-link class="item item-long" :underline="false" href="" target=""
>高校毕业生就业服务专区</el-link
>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
const tabsList = [
{ name: '首页', link: '' },
{ name: '专题招聘', link: '' },
{ name: '灵活就业', link: '' },
{ name: '在线培训', link: '' },
{ name: '军人专区', link: '' },
{ name: '港澳就业', link: '' },
{ name: '校园招聘', link: '' }
]
</script>
<style lang="scss" scoped>
.headers {
box-sizing: border-box;
height: 100%;
display: flex;
align-items: center;
flex-direction: column;
.headers-top {
width: 100%;
background-color: #f0f0f0;
height: 30px;
display: flex;
justify-content: center;
text-align: end;
.content {
// width: 1200px;
min-width: 1200px;
line-height: 30px;
.slash {
color: #606266;
}
}
}
.headers-bottom {
width: 100%;
display: flex;
justify-content: center;
background-color: #ffffff;
.content {
height: 60px;
// width: 1200px;
display: flex;
align-items: center;
.item {
width: 100px;
height: 100%;
line-height: 60px;
text-align: center;
font-weight: 400;
font-size: 16px;
}
.item-long {
width: 180px;
}
}
}
}
</style>
<template>
<div class="layout-container">
<el-container>
<el-header>
<Headers />
</el-header>
<el-main>
<Main />
</el-main>
<el-footer>
<Footer />
</el-footer>
</el-container>
</div>
</template>
<script setup lang="ts">
import Headers from './headers.vue'
import Main from './main.vue'
import Footer from './footer.vue'
</script>
<style lang="scss" scoped>
.layout-container {
background-image: url(https://img2.baidu.com/it/u=622993978,1977535812&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800);
background-size: cover;
background-repeat: no-repeat;
height: 100vh;
min-width: 1200px;
.el-header {
height: 80px;
padding: 0;
}
.el-main {
padding: 0;
}
.el-footer {
padding: 0;
}
}
</style>
<template>
<div class="main-container">
<div class="search-group">
<el-input v-model="searchValue" placeholder="请输入搜索关键字" class="input-with-select">
<template #prepend>
<el-select v-model="selectValue" placeholder="Select" style="width: 115px">
<el-option label="找工作" value="1" />
<el-option label="找企业" value="2" />
<el-option label="找人才" value="3" />
</el-select>
</template>
<template #append>
<el-button :icon="Search" />
</template>
</el-input>
</div>
<div class="banner-group">
<div class="job-menu">
<el-menu class="el-menu-vertical-demo">
<el-menu-item
v-for="item in menuList"
:key="item.index"
@mouseover="mouseover(item)"
@mouseout="mouseout(item)"
>
<template #title>
<div class="menu-item-title">
<span>{{ item.name }}</span>
<el-icon><i-ep-ArrowRight /></el-icon>
</div>
</template>
</el-menu-item>
</el-menu>
<div class="job-menu-sub" @mouseover="mouseover" @mouseout="mouseout">
<el-scrollbar height="400px">
<el-descriptions v-for="item in 10" :key="item" :column="4">
<template #title>
<div style="font-size: 14px; font-weight: 400">销售</div>
</template>
<el-descriptions-item>
<template #default>
<el-link :underline="false">销售业务</el-link>
</template>
</el-descriptions-item>
<el-descriptions-item>
<template #default>
<el-link :underline="false">销售业务</el-link>
</template>
</el-descriptions-item>
<el-descriptions-item>
<template #default>
<el-link :underline="false">销售业务</el-link>
</template>
</el-descriptions-item>
<el-descriptions-item>
<template #default>
<el-link :underline="false">销售业务</el-link>
</template>
</el-descriptions-item>
<el-descriptions-item>
<template #default>
<el-link :underline="false">销售业务</el-link>
</template>
</el-descriptions-item>
</el-descriptions>
</el-scrollbar>
</div>
</div>
<div class="banner-main">
<el-carousel height="410px">
<el-carousel-item v-for="item in 4" :key="item">
<el-image
style="width: 100%; height: 100%"
src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg"
/>
</el-carousel-item>
</el-carousel>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { Search } from '@element-plus/icons-vue'
const searchValue = ref()
const selectValue = ref()
const menuList = [
{
index: 0,
name: '销售|客服|采购|淘宝'
},
{
index: 1,
name: '人力|行政|管理'
},
{
index: 2,
name: '网络|通信|电子|电气'
},
{
index: 3,
name: '市场|媒介|广告|设计'
},
{
index: 4,
name: '生产| 物流|质控|汽车'
},
{
index: 5,
name: '生活| 服务业|超市|百货'
},
{
index: 6,
name: '法律|教育|翻译|出版'
},
{
index: 7,
name: '财会 | 金融 | 保险'
},
{
index: 8,
name: '医疗 | 制药 | 环保'
}
]
const mouseover = (row?: any) => {
const jobMenuJob: any = document.querySelector('.job-menu-sub')
jobMenuJob.style.display = 'block'
}
const mouseout = (row?: any) => {
const jobMenuJob: any = document.querySelector('.job-menu-sub')
jobMenuJob.style.display = 'none'
}
</script>
<style lang="scss" scoped>
.main-container {
display: flex;
flex-direction: column;
align-items: center;
// overflow: hidden;
.search-group {
width: 920px;
border-radius: 20px;
margin: 40px 0;
.el-input {
height: 100%;
:deep(.el-input__wrapper) {
height: 60px;
}
}
}
.banner-group {
// width: 1200px;
height: 424px;
display: flex;
.job-menu {
width: 238px;
height: 410px;
position: relative;
padding: 16px 0;
background-color: #ffffff;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
box-sizing: border-box;
// background: rgba(79, 90, 102, 0.6);
.el-menu {
border-right: 0;
// background: transparent;
.menu-item-title {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
.el-menu-item {
// color: #ffffff !important;
height: 42px;
}
}
.job-menu-sub {
display: none;
position: absolute;
top: 0;
left: 238px;
z-index: 10;
width: 700px;
height: 410px;
background: #fff;
.el-scrollbar {
padding: 16px 23px 0 24px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
:deep(.el-descriptions__label) {
margin-right: 0;
}
}
}
.banner-main {
width: 700px;
height: 410px;
}
}
}
:deep(.input-with-select .el-input-group__prepend) {
background-color: #ffffff;
}
</style>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
\ No newline at end of file
import { createApp } from 'vue'
import App from './App.vue'
import router from './routers'
import store from './stores'
const app = createApp(App)
app.use(router)
app.use(store)
app.mount('#app')
export default [
{
url: '/api/getUsers',
method: 'get',
response: () => {
return {
code: 200,
message: 'ok',
data: {
'rows|10': [
{
id: '@guid',
name: '@cname',
'age|20-30': 23,
'job|1': ['前端工程师', '后端工程师', 'UI工程师', '需求工程师']
}
]
}
}
}
}
]
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{
path: '/',
name: 'layout',
//使用import可以路由懒加载,如果不使用,太多组件一起加载会造成白屏
component: () => import('@/Layout/index.vue')
}
//{
//配置404页面
//path: '/:catchAll(.*)',
//name: '404',
//component: () => import(''),
//}
]
// 路由
const router = createRouter({
history: createWebHistory(),
routes
})
// 导出
export default router
import request from '@/services'
export const getUsers = () => {
return request.get('/getUsers')
}
import { ElMessage } from 'element-plus'
/**
* @description: 校验网络请求状态码
* @param {Number} status
* @return void
*/
export const checkStatus = (status: number): void => {
switch (status) {
case 400:
ElMessage.error('请求失败!请您稍后重试')
break
case 401:
ElMessage.error('登录失效!请您重新登录')
break
case 403:
ElMessage.error('当前账号无权限访问!')
break
case 404:
ElMessage.error('你所访问的资源不存在!')
break
case 405:
ElMessage.error('请求方式错误!请您稍后重试')
break
case 408:
ElMessage.error('请求超时!请您稍后重试')
break
case 500:
ElMessage.error('服务异常!')
break
case 502:
ElMessage.error('网关错误!')
break
case 503:
ElMessage.error('服务不可用!')
break
case 504:
ElMessage.error('网关超时!')
break
default:
ElMessage.error('请求失败!')
}
}
import axios, {
AxiosInstance,
AxiosError,
AxiosRequestConfig,
InternalAxiosRequestConfig,
AxiosResponse
} from 'axios'
import { ElMessage } from 'element-plus'
import { useGlobalStore } from '@/stores'
import { LOGIN_URL } from '@/utils'
import router from '@/routers'
// 数据返回的接口
// 定义请求响应参数,不含data
interface Result {
code: number
msg: string
}
// 请求响应参数,包含data
interface ResultData<T = any> extends Result {
data?: T
}
let URL: string = '/api'
enum RequestEnums {
TIMEOUT = 20000, // 请求超时
OVERDUE = 600, // 登录失败
FAIL = 999, // 请求失败
SUCCESS = 200 // 请求成功
}
const config = {
// 默认地址
baseURL: URL as string,
// 设置超时时间
timeout: RequestEnums.TIMEOUT as number,
// 跨域时候允许携带凭证
withCredentials: true,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}
class RequestHttp {
// 定义成员变量并指定类型
service: AxiosInstance
public constructor(config: AxiosRequestConfig) {
// 实例化axios
this.service = axios.create(config)
/**
* 请求拦截器
* 客户端发送请求 -> [请求拦截器] -> 服务器
* token校验(JWT) : 接受服务器返回的token,存储到本地储存当中
*/
this.service.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
const globalStore = useGlobalStore()
// * 如果当前请求不需要显示 loading,在 api 服务中通过指定的第三个参数: { headers: { noLoading: true } }来控制不显示loading,参见getMenuList()
// config.headers!.noLoading || showFullScreenLoading();
const token = globalStore.token
if (config.headers && typeof config.headers?.set === 'function')
config.headers.set('x-access-token', globalStore.token)
return config
},
// 请求报错
(error: AxiosError) => {
return Promise.reject(error)
}
),
/**
* 响应拦截器
* 服务器换返回信息 -> [拦截统一处理] -> 客户端JS获取到信息
*/
this.service.interceptors.response.use(
(response: AxiosResponse) => {
const { data, config } = response // 解构
const globalStore = useGlobalStore()
// 未携带token或token失效
if (data.code === RequestEnums.OVERDUE) {
// 登录信息失效,应跳转到登录页面,并清空本地的token
globalStore.setToken('')
ElMessage.error(data.msg)
router.replace(LOGIN_URL)
return Promise.reject(data)
}
// 全局错误信息拦截(防止下载文件得时候返回数据流,没有code,直接报错)
if (data.code && data.code !== RequestEnums.SUCCESS) {
ElMessage.error(data.msg) // 此处也可以使用组件提示报错信息
return Promise.reject(data)
}
// * 成功请求(在页面上除非特殊情况,否则不用在页面处理失败逻辑)
return data
},
(error: AxiosError) => {
const { response } = error
// 请求超时 && 网络错误单独判断,没有 response
if (error.message.indexOf('timeout') !== -1) ElMessage.error('请求超时!请您稍后重试')
if (error.message.indexOf('Network Error') !== -1)
ElMessage.error('网络错误!请您稍后重试')
// 根据响应的错误状态码,做不同的处理
if (response) this.handleCode(response.status)
// 服务器结果都没有返回(可能服务器错误可能客户端断网),断网处理:可以跳转到断网页面
if (!window.navigator.onLine) router.replace('/500')
return Promise.reject(error)
}
)
}
handleCode(code: number): void {
switch (code) {
case 401:
ElMessage.error('登录失败,请重新登录')
break
default:
ElMessage.error('请求失败')
break
}
}
// 常用方法封装
get<T>(url: string, params?: Object, _object = {}): Promise<ResultData<T>> {
return this.service.get(url, { params, ..._object })
}
post<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
return this.service.post(url, params, _object)
}
put<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
return this.service.put(url, params, _object)
}
delete<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
return this.service.delete(url, { params, ..._object })
}
download(url: string, params?: object, _object = {}): Promise<BlobPart> {
return this.service.post(url, params, { ..._object, responseType: 'blob' })
}
}
// 导出一个实例对象
export default new RequestHttp(config)
import { defineStore, createPinia } from 'pinia'
import piniaPersistConfig from '../utils/piniaPersist'
import piniaPluginPersist from 'pinia-plugin-persist'
// defineStore('global',{..}) 在devtools 就使用 global 这个名
export const useGlobalStore = defineStore('globalStore', {
// 相当于data
state: () => {
return {
// 所有这些属性都将自动推断其类型,如果推断失败可以试下 as xxx
token: ''
}
},
// 相当于计算属性
getters: {},
// 相当于vuex的 mutation + action,可以同时写同步和异步的代码
actions: {
setToken(token: string) {
this.token = token
},
persist: piniaPersistConfig('globalStore')
}
})
const pinia = createPinia()
pinia.use(piniaPluginPersist)
export default pinia
export const LOGIN_URL = 'login'
import { PersistStrategy } from 'pinia-plugin-persist'
/**
* @description pinia持久化参数配置
* @param {String} key 存储到持久化的 name
* @param {Array} paths 需要持久化的 state name
* @return persist
* */
const piniaPersistConfig = (key: string, paths?: any[]) => {
const persist: PersistStrategy = {
key,
storage: localStorage,
// storage: sessionStorage,
paths
}
return persist
}
export default piniaPersistConfig
<template>
<div class="home-container">home {{ num }}</div>
<el-button @click="num++">点击加1</el-button>
</template>
<script setup lang="ts" name="index">
import { getUsers } from '@/services/api/home'
const init = async () => {
const res = await getUsers()
console.log(res, 'kkk')
}
init()
const num = ref(0)
</script>
<style lang="scss" scoped>
.home-container {
font-size: 40px;
}
</style>
/* eslint-disable */
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
\ No newline at end of file
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
"lib": ["esnext", "dom", "dom.iterable", "scripthost"]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx",
"types/auto-imports.d.ts"
],
"exclude": ["node_modules"]
}
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}
/* 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, InjectionKey, PropType, Ref, VNode } from 'vue'
}
/* 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']
ElCarousel: typeof import('element-plus/es')['ElCarousel']
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
ElFooter: typeof import('element-plus/es')['ElFooter']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElImage: typeof import('element-plus/es')['ElImage']
ElInput: typeof import('element-plus/es')['ElInput']
ElLink: typeof import('element-plus/es')['ElLink']
ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup']
ElOption: typeof import('element-plus/es')['ElOption']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
ElTag: typeof import('element-plus/es')['ElTag']
IEpArrowRight: typeof import('~icons/ep/arrow-right')['default']
IEpArrowRightBold: typeof import('~icons/ep/arrow-right-bold')['default']
IEpDocument: typeof import('~icons/ep/document')['default']
IEpMenu: typeof import('~icons/ep/menu')['default']
IEpSetting: typeof import('~icons/ep/setting')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 自动导入icon图标
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
// 导入自动装配插件
import AutoImport from 'unplugin-auto-import/vite'
//自动导入ui-组件
import Components from 'unplugin-vue-components/vite'
// 配置@别名
import { resolve } from 'path'
// 按需引入element-plus
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
// Vue3 setup 语法糖下定义组件名称 <script lang="ts" setup name="home">
import VueSetupExtend from 'vite-plugin-vue-setup-extend'
// 引入viteMockServe 配置mock
import { viteMockServe } from 'vite-plugin-mock'
import eslintPlugin from 'vite-plugin-eslint'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
VueSetupExtend(),
eslintPlugin({
include: ['src/**/*.ts', 'src/**/*.vue', 'src/*.ts', 'src/*.vue']
}),
viteMockServe({
mockPath: 'src/mock/'
}),
// 配置自动装载配置
AutoImport({
// 生成配置文件,如果是ts项目,通常我们会把声明文件放在根目录/types中,注意,这个文件夹需要先建好,否则可能导致等下无法往里生成auto-imports.d.ts文件
dts: 'types/auto-imports.d.ts',
imports: ['vue', 'vue-router', 'pinia'],
resolvers: [
ElementPlusResolver(),
IconsResolver({
prefix: 'Icon'
})
],
eslintrc: {
// 默认false, true启用。生成一次就可以,
// 避免每次工程启动都生成,
// 一旦生成配置文件之后,最好把enable关掉,即改成false。
// 否则这个文件每次会在重新加载的时候重新生成,这会导致eslint有时会找不到这个文件。当需要更新配置文件的时候,再重新打开
enabled: false,
// 生成json文件,可以不配置该项,默认就是将生成在根目录
filepath: './.eslintrc-auto-import.json',
globalsPropValue: true
}
}),
Components({
// 引入组件的,包括自定义组件
// 存放的位置
dts: 'types/components.d.ts',
resolvers: [
ElementPlusResolver(),
IconsResolver({
enabledCollections: ['ep']
})
]
}),
Icons({
autoInstall: true
})
],
// ↓解析配置
resolve: {
// ↓路径别名
alias: {
'@': resolve(__dirname, './src')
}
},
server: {
port: 4000, //设置服务启动端口号,是一个可选项,不要设置为本机的端口号,可能会发生冲突
open: true, //是否自动打开浏览器,可选项
cors: true, //允许跨域。
host: '0.0.0.0',
// 设置代理
proxy: {
// 将请求代理到另一个服务器
'/api': {
target: 'http://127.0.0.1:5173', //这是你要跨域请求的地址前缀
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
},
build: {
minify: 'terser',
terserOptions: {
compress: {
//生产环境时移除console.log()
drop_console: true,
drop_debugger: true
}
}
}
})
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论