commit
1900916f45
27 changed files with 3212 additions and 0 deletions
-
24.gitignore
-
3.vscode/extensions.json
-
5README.md
-
13index.html
-
1984package-lock.json
-
38package.json
-
1public/vite.svg
-
5src/ shims-vue.d.ts
-
24src/App.vue
-
79src/assets/style.css
-
1src/assets/vue.svg
-
15src/components/Footer.vue
-
61src/components/NavHeader.vue
-
62src/components/SideBar.vue
-
12src/main.ts
-
87src/pages/HomeView.vue
-
266src/pages/ProductView.vue
-
155src/pages/SettingView.vue
-
249src/pages/UserView.vue
-
35src/router/index.ts
-
33src/utils/http.ts
-
3src/utils/test.ts
-
1src/vite-env.d.ts
-
15tsconfig.app.json
-
9tsconfig.json
-
25tsconfig.node.json
-
7vite.config.ts
@ -0,0 +1,24 @@ |
|||
# 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? |
@ -0,0 +1,3 @@ |
|||
{ |
|||
"recommendations": ["Vue.volar"] |
|||
} |
@ -0,0 +1,5 @@ |
|||
# Vue 3 + TypeScript + Vite |
|||
|
|||
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more. |
|||
|
|||
Learn more about the recommended Project Setup and IDE Support in the [Vue Docs TypeScript Guide](https://vuejs.org/guide/typescript/overview.html#project-setup). |
@ -0,0 +1,13 @@ |
|||
<!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>Vite + Vue + TS</title> |
|||
</head> |
|||
<body> |
|||
<div id="app"></div> |
|||
<script type="module" src="/src/main.ts"></script> |
|||
</body> |
|||
</html> |
1984
package-lock.json
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,38 @@ |
|||
{ |
|||
"name": "elementplus_demo", |
|||
"private": true, |
|||
"version": "0.0.0", |
|||
"type": "module", |
|||
"scripts": { |
|||
"dev": "vite", |
|||
"build": "vue-tsc -b && vite build", |
|||
"preview": "vite preview" |
|||
}, |
|||
"dependencies": { |
|||
"axios": "^1.10.0", |
|||
"element-plus": "^2.10.2", |
|||
"vue": "^3.5.13", |
|||
"vue-route": "^1.1.5", |
|||
"vue-router": "^4.5.1" |
|||
}, |
|||
"devDependencies": { |
|||
"@vitejs/plugin-vue": "^5.2.3", |
|||
"@vue/tsconfig": "^0.7.0", |
|||
"typescript": "~5.8.3", |
|||
"vite": "^6.3.5", |
|||
"vue-tsc": "^2.2.8" |
|||
}, |
|||
"compilerOptions": { |
|||
"types": [ |
|||
"vue/global-types" |
|||
] |
|||
}, |
|||
"include": [ |
|||
"src/**/*.ts", |
|||
"src/**/*.d.ts", |
|||
"src/**/*.tsx", |
|||
"src/**/*.vue" |
|||
] |
|||
} |
|||
|
|||
|
@ -0,0 +1 @@ |
|||
<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> |
@ -0,0 +1,5 @@ |
|||
declare module '*.vue' { |
|||
import { DefineComponent } from 'vue' |
|||
const component: DefineComponent<{}, {}, any> |
|||
export default component |
|||
} |
@ -0,0 +1,24 @@ |
|||
<template> |
|||
<div id="app"> |
|||
<NavHeader /> |
|||
<router-view /> |
|||
<Footer /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import NavHeader from './components/NavHeader.vue' |
|||
import Footer from './components/Footer.vue' |
|||
</script> |
|||
|
|||
<style> |
|||
#app { |
|||
font-family: Avenir, Helvetica, Arial, sans-serif; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
color: #2c3e50; |
|||
height: 100vh; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
</style> |
@ -0,0 +1,79 @@ |
|||
:root { |
|||
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; |
|||
line-height: 1.5; |
|||
font-weight: 400; |
|||
|
|||
color-scheme: light dark; |
|||
color: rgba(255, 255, 255, 0.87); |
|||
background-color: #242424; |
|||
|
|||
font-synthesis: none; |
|||
text-rendering: optimizeLegibility; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
} |
|||
|
|||
a { |
|||
font-weight: 500; |
|||
color: #646cff; |
|||
text-decoration: inherit; |
|||
} |
|||
a:hover { |
|||
color: #535bf2; |
|||
} |
|||
|
|||
body { |
|||
margin: 0; |
|||
display: flex; |
|||
place-items: center; |
|||
min-width: 320px; |
|||
min-height: 100vh; |
|||
} |
|||
|
|||
h1 { |
|||
font-size: 3.2em; |
|||
line-height: 1.1; |
|||
} |
|||
|
|||
button { |
|||
border-radius: 8px; |
|||
border: 1px solid transparent; |
|||
padding: 0.6em 1.2em; |
|||
font-size: 1em; |
|||
font-weight: 500; |
|||
font-family: inherit; |
|||
background-color: #1a1a1a; |
|||
cursor: pointer; |
|||
transition: border-color 0.25s; |
|||
} |
|||
button:hover { |
|||
border-color: #646cff; |
|||
} |
|||
button:focus, |
|||
button:focus-visible { |
|||
outline: 4px auto -webkit-focus-ring-color; |
|||
} |
|||
|
|||
.card { |
|||
padding: 2em; |
|||
} |
|||
|
|||
#app { |
|||
max-width: 1280px; |
|||
margin: 0 auto; |
|||
padding: 2rem; |
|||
text-align: center; |
|||
} |
|||
|
|||
@media (prefers-color-scheme: light) { |
|||
:root { |
|||
color: #213547; |
|||
background-color: #ffffff; |
|||
} |
|||
a:hover { |
|||
color: #747bff; |
|||
} |
|||
button { |
|||
background-color: #f9f9f9; |
|||
} |
|||
} |
@ -0,0 +1 @@ |
|||
<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> |
@ -0,0 +1,15 @@ |
|||
<template> |
|||
<el-footer class="text-center text-gray-500"> |
|||
© 2025 ElementPlus Demo. All rights reserved. |
|||
</el-footer> |
|||
</template> |
|||
|
|||
<script setup> |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.el-footer { |
|||
line-height: 60px; |
|||
border-top: 1px solid #ebeef5; |
|||
} |
|||
</style> |
@ -0,0 +1,61 @@ |
|||
<template> |
|||
<el-header> |
|||
<el-row> |
|||
<el-col :span="6"> |
|||
<h1 class="text-2xl font-bold text-white">ElementPlus Demo</h1> |
|||
</el-col> |
|||
<el-col :span="18"> |
|||
<el-menu |
|||
mode="horizontal" |
|||
:default-active="activeMenu" |
|||
background-color="#304156" |
|||
text-color="#fff" |
|||
active-text-color="#409EFF" |
|||
@select="handleSelect" |
|||
> |
|||
<el-menu-item index="1" route="/">首页</el-menu-item> |
|||
<el-menu-item index="2" route="/product">商品管理</el-menu-item> |
|||
<el-menu-item index="3" route="/user">用户管理</el-menu-item> |
|||
<el-sub-menu index="4"> |
|||
<template #title>系统设置</template> |
|||
<el-menu-item index="4-1" route="/setting/permissions">权限设置</el-menu-item> |
|||
<el-menu-item index="4-2" route="/setting/interface">界面设置</el-menu-item> |
|||
</el-sub-menu> |
|||
</el-menu> |
|||
</el-col> |
|||
</el-row> |
|||
</el-header> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref } from 'vue' |
|||
import { useRouter } from 'vue-router' |
|||
|
|||
const router = useRouter() |
|||
const activeMenu = ref('1') |
|||
|
|||
const handleSelect = (key) => { |
|||
// 根据菜单项的index映射到对应的路由路径 |
|||
const pathMap = { |
|||
'1': '/', |
|||
'2': '/product', |
|||
'3': '/user', |
|||
'4-1': '/setting/permissions', |
|||
'4-2': '/setting/interface' |
|||
} |
|||
|
|||
if (pathMap[key]) { |
|||
router.push(pathMap[key]) |
|||
activeMenu.value = key |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.el-header { |
|||
background-color: #304156; |
|||
color: #fff; |
|||
line-height: 60px; |
|||
padding: 0 20px; |
|||
} |
|||
</style> |
@ -0,0 +1,62 @@ |
|||
<template> |
|||
<el-aside width="200px"> |
|||
<el-menu |
|||
:default-active="activeKey" |
|||
class="el-menu-vertical" |
|||
@open="handleOpen" |
|||
@close="handleClose" |
|||
background-color="#fff" |
|||
text-color="#303133" |
|||
active-text-color="#409EFF" |
|||
> |
|||
<el-sub-menu index="1"> |
|||
<template #title> |
|||
<i class="el-icon-location"></i> |
|||
<span>导航一</span> |
|||
</template> |
|||
<el-menu-item-group> |
|||
<template #title>分组一</template> |
|||
<el-menu-item index="1-1">选项1</el-menu-item> |
|||
<el-menu-item index="1-2">选项2</el-menu-item> |
|||
</el-menu-item-group> |
|||
<el-menu-item-group title="分组二"> |
|||
<el-menu-item index="1-3">选项3</el-menu-item> |
|||
</el-menu-item-group> |
|||
<el-sub-menu index="1-4"> |
|||
<template #title>选项4</template> |
|||
<el-menu-item index="1-4-1">子选项1</el-menu-item> |
|||
<el-menu-item index="1-4-2">子选项2</el-menu-item> |
|||
</el-sub-menu> |
|||
</el-sub-menu> |
|||
<el-menu-item index="2"> |
|||
<i class="el-icon-menu"></i> |
|||
<span>导航二</span> |
|||
</el-menu-item> |
|||
<el-menu-item index="3"> |
|||
<i class="el-icon-document"></i> |
|||
<span>导航三</span> |
|||
</el-menu-item> |
|||
</el-menu> |
|||
</el-aside> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref } from 'vue' |
|||
|
|||
const activeKey = ref('1-1') |
|||
|
|||
const handleOpen = (key, keyPath) => { |
|||
console.log(key, keyPath) |
|||
} |
|||
|
|||
const handleClose = (key, keyPath) => { |
|||
console.log(key, keyPath) |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.el-aside { |
|||
background-color: #f9fafc; |
|||
border-right: 1px solid #ebeef5; |
|||
} |
|||
</style> |
@ -0,0 +1,12 @@ |
|||
import {createApp} from 'vue' |
|||
import ElementPlus from 'element-plus' |
|||
import 'element-plus/dist/index.css' |
|||
import App from './App.vue' |
|||
import router from './router' |
|||
|
|||
const app = createApp(App) |
|||
|
|||
app.use(ElementPlus) |
|||
app.use(router) |
|||
|
|||
app.mount('#app') |
@ -0,0 +1,87 @@ |
|||
<template> |
|||
<div class="flex h-screen"> |
|||
<SideBar /> |
|||
<div class="flex-1 p-4 overflow-auto"> |
|||
<el-card class="mb-4"> |
|||
<template #header> |
|||
<div class="flex justify-between items-center"> |
|||
<span>数据统计</span> |
|||
<el-button type="primary" size="small">刷新</el-button> |
|||
</div> |
|||
</template> |
|||
<el-row :gutter="20"> |
|||
<el-col :span="6"> |
|||
<el-card class="text-center"> |
|||
<div class="text-3xl font-bold text-blue-500">¥123,456</div> |
|||
<div class="text-gray-500 mt-2">今日销售额</div> |
|||
</el-card> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-card class="text-center"> |
|||
<div class="text-3xl font-bold text-green-500">2,451</div> |
|||
<div class="text-gray-500 mt-2">订单数量</div> |
|||
</el-card> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-card class="text-center"> |
|||
<div class="text-3xl font-bold text-orange-500">1,284</div> |
|||
<div class="text-gray-500 mt-2">用户数</div> |
|||
</el-card> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-card class="text-center"> |
|||
<div class="text-3xl font-bold text-purple-500">87%</div> |
|||
<div class="text-gray-500 mt-2">转化率</div> |
|||
</el-card> |
|||
</el-col> |
|||
</el-row> |
|||
</el-card> |
|||
|
|||
<el-card> |
|||
<template #header> |
|||
<span>最近订单</span> |
|||
</template> |
|||
<el-table :data="orderData" stripe style="width: 100%"> |
|||
<el-table-column prop="orderId" label="订单ID" width="150"></el-table-column> |
|||
<el-table-column prop="customer" label="客户" width="120"></el-table-column> |
|||
<el-table-column prop="product" label="商品" width="180"></el-table-column> |
|||
<el-table-column prop="amount" label="金额" width="100"> |
|||
<template #default="scope"> |
|||
¥{{ scope.row.amount }} |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="status" label="状态" width="100"> |
|||
<template #default="scope"> |
|||
<el-tag :type="getStatusType(scope.row.status)">{{ scope.row.status }}</el-tag> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="date" label="日期" width="160"></el-table-column> |
|||
</el-table> |
|||
</el-card> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref, computed } from 'vue' |
|||
import SideBar from '../components/SideBar.vue' |
|||
|
|||
const orderData = ref([ |
|||
{ orderId: 'ORD-20250618-001', customer: '张三', product: 'iPhone 14 Pro', amount: 8999, status: '已支付', date: '2025-06-18 10:23' }, |
|||
{ orderId: 'ORD-20250618-002', customer: '李四', product: 'MacBook Air', amount: 11999, status: '已发货', date: '2025-06-18 09:45' }, |
|||
{ orderId: 'ORD-20250618-003', customer: '王五', product: 'iPad Pro', amount: 6799, status: '已支付', date: '2025-06-18 08:12' }, |
|||
{ orderId: 'ORD-20250618-004', customer: '赵六', product: 'Apple Watch', amount: 3199, status: '待支付', date: '2025-06-18 07:30' }, |
|||
{ orderId: 'ORD-20250618-005', customer: '钱七', product: 'AirPods Pro', amount: 1799, status: '已完成', date: '2025-06-18 06:55' } |
|||
]) |
|||
|
|||
const getStatusType = (status) => { |
|||
const statusMap = { |
|||
'已支付': 'primary', |
|||
'已发货': 'success', |
|||
'待支付': 'warning', |
|||
'已完成': 'info', |
|||
'已取消': 'danger' |
|||
} |
|||
return statusMap[status] || 'default' |
|||
} |
|||
</script> |
@ -0,0 +1,266 @@ |
|||
<template> |
|||
<div class="flex h-screen"> |
|||
<SideBar /> |
|||
<div class="flex-1 p-4 overflow-auto"> |
|||
<el-card> |
|||
<template #header> |
|||
<div class="flex justify-between items-center"> |
|||
<span>商品列表</span> |
|||
<el-button type="primary" @click="handleCreateProduct">新增商品</el-button> |
|||
</div> |
|||
</template> |
|||
|
|||
<el-form :inline="true" :model="searchForm" class="mb-4"> |
|||
<el-form-item label="商品名称"> |
|||
<el-input v-model="searchForm.name" placeholder="请输入商品名称" clearable></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="分类"> |
|||
<el-select v-model="searchForm.category" placeholder="请选择分类" clearable> |
|||
<el-option label="电子产品" value="electronics"></el-option> |
|||
<el-option label="服装鞋帽" value="clothing"></el-option> |
|||
<el-option label="家居用品" value="household"></el-option> |
|||
<el-option label="食品饮料" value="food"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="状态"> |
|||
<el-select v-model="searchForm.status" placeholder="请选择状态" clearable> |
|||
<el-option label="上架" value="active"></el-option> |
|||
<el-option label="下架" value="inactive"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" @click="handleSearch">搜索</el-button> |
|||
<el-button @click="resetSearch">重置</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
|
|||
<el-table :data="tableData" stripe style="width: 100%"> |
|||
<el-table-column type="selection" width="55"></el-table-column> |
|||
<el-table-column prop="id" label="ID" width="100"></el-table-column> |
|||
<el-table-column prop="name" label="商品名称"></el-table-column> |
|||
<el-table-column prop="category" label="分类" width="120"> |
|||
<template #default="scope"> |
|||
{{ getCategoryName(scope.row.category) }} |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="price" label="价格" width="100"> |
|||
<template #default="scope"> |
|||
¥{{ scope.row.price }} |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="stock" label="库存" width="100"></el-table-column> |
|||
<el-table-column prop="status" label="状态" width="100"> |
|||
<template #default="scope"> |
|||
<el-tag :type="scope.row.status === 'active' ? 'success' : 'danger'"> |
|||
{{ scope.row.status === 'active' ? '上架' : '下架' }} |
|||
</el-tag> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column label="操作" width="160"> |
|||
<template #default="scope"> |
|||
<el-button size="small" type="primary" @click="handleEdit(scope.row)">编辑</el-button> |
|||
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
|
|||
<el-pagination |
|||
class="mt-4 flex justify-center" |
|||
@size-change="handleSizeChange" |
|||
@current-change="handleCurrentChange" |
|||
:current-page="currentPage" |
|||
:page-sizes="[10, 20, 30, 50]" |
|||
:page-size="pageSize" |
|||
layout="total, sizes, prev, pager, next, jumper" |
|||
:total="total" |
|||
></el-pagination> |
|||
</el-card> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref, reactive, toRefs } from 'vue' |
|||
import SideBar from '../components/SideBar.vue' |
|||
|
|||
// 搜索表单 |
|||
const searchForm = reactive({ |
|||
name: '', |
|||
category: '', |
|||
status: '' |
|||
}) |
|||
|
|||
// 表格数据 |
|||
const tableData = ref([ |
|||
{ id: 1, name: 'iPhone 14 Pro', category: 'electronics', price: 8999, stock: 100, status: 'active' }, |
|||
{ id: 2, name: 'MacBook Air', category: 'electronics', price: 11999, stock: 50, status: 'active' }, |
|||
{ id: 3, name: 'iPad Pro', category: 'electronics', price: 6799, stock: 80, status: 'active' }, |
|||
{ id: 4, name: 'Apple Watch', category: 'electronics', price: 3199, stock: 120, status: 'active' }, |
|||
{ id: 5, name: 'AirPods Pro', category: 'electronics', price: 1799, stock: 200, status: 'inactive' }, |
|||
{ id: 6, name: 'T恤', category: 'clothing', price: 99, stock: 300, status: 'active' }, |
|||
{ id: 7, name: '牛仔裤', category: 'clothing', price: 299, stock: 150, status: 'active' }, |
|||
{ id: 8, name: '运动鞋', category: 'clothing', price: 599, stock: 90, status: 'active' }, |
|||
{ id: 9, name: '沙发', category: 'household', price: 3999, stock: 20, status: 'active' }, |
|||
{ id: 10, name: '餐桌', category: 'household', price: 1999, stock: 30, status: 'inactive' } |
|||
]) |
|||
|
|||
// 分页 |
|||
const currentPage = ref(1) |
|||
const pageSize = ref(10) |
|||
const total = ref(100) |
|||
|
|||
// 对话框 |
|||
const dialogVisible = ref(false) |
|||
const dialogTitle = ref('') |
|||
const editForm = reactive({ |
|||
id: null, |
|||
name: '', |
|||
category: 'electronics', |
|||
price: 0, |
|||
stock: 0, |
|||
status: 'active' |
|||
}) |
|||
|
|||
// 表单验证规则 |
|||
const rules = reactive({ |
|||
name: [ |
|||
{ required: true, message: '请输入商品名称', trigger: 'blur' } |
|||
], |
|||
category: [ |
|||
{ required: true, message: '请选择商品分类', trigger: 'change' } |
|||
], |
|||
price: [ |
|||
{ required: true, message: '请输入价格', trigger: 'blur' }, |
|||
{ type: 'number', message: '价格必须为数字值', trigger: 'blur' } |
|||
], |
|||
stock: [ |
|||
{ required: true, message: '请输入库存', trigger: 'blur' }, |
|||
{ type: 'number', message: '库存必须为数字值', trigger: 'blur' } |
|||
] |
|||
}) |
|||
|
|||
// 表单引用 |
|||
const editFormRef = ref(null) |
|||
|
|||
// 分类映射 |
|||
const categoryMap = { |
|||
'electronics': '电子产品', |
|||
'clothing': '服装鞋帽', |
|||
'household': '家居用品', |
|||
'food': '食品饮料' |
|||
} |
|||
|
|||
// 获取分类名称 |
|||
const getCategoryName = (category) => { |
|||
return categoryMap[category] || category |
|||
} |
|||
|
|||
// 搜索方法 |
|||
const handleSearch = () => { |
|||
console.log('搜索条件:', searchForm) |
|||
// 这里可以添加搜索逻辑 |
|||
} |
|||
|
|||
const resetSearch = () => { |
|||
searchForm.name = '' |
|||
searchForm.category = '' |
|||
searchForm.status = '' |
|||
} |
|||
|
|||
// 表格操作 |
|||
const handleEdit = (row) => { |
|||
// 复制数据到编辑表单 |
|||
Object.assign(editForm, row) |
|||
dialogTitle.value = '编辑商品' |
|||
dialogVisible.value = true |
|||
} |
|||
|
|||
const handleDelete = (row) => { |
|||
elMessageBox.confirm( |
|||
'确定要删除该商品吗?', |
|||
'提示', |
|||
{ |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning' |
|||
} |
|||
).then(() => { |
|||
// 从表格数据中删除 |
|||
const index = tableData.value.findIndex(item => item.id === row.id) |
|||
if (index !== -1) { |
|||
tableData.value.splice(index, 1) |
|||
elMessage({ |
|||
type: 'success', |
|||
message: '删除成功!' |
|||
}) |
|||
} |
|||
}).catch(() => { |
|||
elMessage({ |
|||
type: 'info', |
|||
message: '已取消删除' |
|||
}) |
|||
}) |
|||
} |
|||
|
|||
// 分页事件处理 |
|||
const handleSizeChange = (newSize) => { |
|||
pageSize.value = newSize |
|||
console.log('每页条数:', newSize) |
|||
} |
|||
|
|||
const handleCurrentChange = (newPage) => { |
|||
currentPage.value = newPage |
|||
console.log('当前页码:', newPage) |
|||
} |
|||
|
|||
// 创建商品 |
|||
const handleCreateProduct = () => { |
|||
// 清空表单 |
|||
Object.keys(editForm).forEach(key => { |
|||
if (key === 'id') { |
|||
editForm[key] = null |
|||
} else if (key === 'status') { |
|||
editForm[key] = 'active' |
|||
} else if (key === 'category') { |
|||
editForm[key] = 'electronics' |
|||
} else { |
|||
editForm[key] = '' |
|||
} |
|||
}) |
|||
|
|||
dialogTitle.value = '新增商品' |
|||
dialogVisible.value = true |
|||
} |
|||
|
|||
// 保存商品 |
|||
const saveProduct = () => { |
|||
editFormRef.value.validate((valid) => { |
|||
if (valid) { |
|||
// 模拟保存操作 |
|||
setTimeout(() => { |
|||
dialogVisible.value = false |
|||
elMessage({ |
|||
type: 'success', |
|||
message: dialogTitle.value === '新增商品' ? '创建成功!' : '更新成功!' |
|||
}) |
|||
|
|||
// 更新表格数据 |
|||
if (editForm.id) { |
|||
// 更新现有商品 |
|||
const index = tableData.value.findIndex(item => item.id === editForm.id) |
|||
if (index !== -1) { |
|||
tableData.value.splice(index, 1, { ...editForm }) |
|||
} |
|||
} else { |
|||
// 创建新商品 |
|||
const newId = Math.max(...tableData.value.map(item => item.id)) + 1 |
|||
tableData.value.unshift({ ...editForm, id: newId }) |
|||
} |
|||
}, 500) |
|||
} else { |
|||
console.log('验证失败') |
|||
return false |
|||
} |
|||
}) |
|||
} |
|||
</script> |
@ -0,0 +1,155 @@ |
|||
<template> |
|||
<div class="flex h-screen"> |
|||
<SideBar /> |
|||
<div class="flex-1 p-4 overflow-auto"> |
|||
<el-card> |
|||
<template #header> |
|||
<span>系统设置</span> |
|||
</template> |
|||
|
|||
<el-tabs v-model="activeTab" type="card"> |
|||
<el-tab-pane label="基本设置" name="basic"> |
|||
<el-form :model="basicSettings" label-width="120px" class="mt-4"> |
|||
<el-form-item label="网站名称"> |
|||
<el-input v-model="basicSettings.siteName"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="网站URL"> |
|||
<el-input v-model="basicSettings.siteUrl"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="网站描述"> |
|||
<el-input type="textarea" v-model="basicSettings.siteDescription" rows="4"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="联系邮箱"> |
|||
<el-input v-model="basicSettings.contactEmail"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="联系电话"> |
|||
<el-input v-model="basicSettings.contactPhone"></el-input> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" @click="saveBasicSettings">保存设置</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-tab-pane> |
|||
|
|||
<el-tab-pane label="界面设置" name="interface"> |
|||
<el-form :model="interfaceSettings" label-width="120px" class="mt-4"> |
|||
<el-form-item label="主题颜色"> |
|||
<el-color-picker v-model="interfaceSettings.themeColor"></el-color-picker> |
|||
</el-form-item> |
|||
<el-form-item label="侧边栏宽度"> |
|||
<el-input-number v-model="interfaceSettings.sidebarWidth" :min="180" :max="300" step="10"></el-input-number> |
|||
</el-form-item> |
|||
<el-form-item label="分页大小"> |
|||
<el-input-number v-model="interfaceSettings.pageSize" :min="5" :max="100" step="5"></el-input-number> |
|||
</el-form-item> |
|||
<el-form-item label="显示头部"> |
|||
<el-switch v-model="interfaceSettings.showHeader"></el-switch> |
|||
</el-form-item> |
|||
<el-form-item label="显示页脚"> |
|||
<el-switch v-model="interfaceSettings.showFooter"></el-switch> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" @click="saveInterfaceSettings">保存设置</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-tab-pane> |
|||
|
|||
<el-tab-pane label="权限设置" name="permissions"> |
|||
<el-form :model="permissionSettings" label-width="120px" class="mt-4"> |
|||
<el-form-item label="用户管理权限"> |
|||
<el-checkbox-group v-model="permissionSettings.userPermissions"> |
|||
<el-checkbox label="view">查看</el-checkbox> |
|||
<el-checkbox label="create">创建</el-checkbox> |
|||
<el-checkbox label="edit">编辑</el-checkbox> |
|||
<el-checkbox label="delete">删除</el-checkbox> |
|||
</el-checkbox-group> |
|||
</el-form-item> |
|||
<el-form-item label="商品管理权限"> |
|||
<el-checkbox-group v-model="permissionSettings.productPermissions"> |
|||
<el-checkbox label="view">查看</el-checkbox> |
|||
<el-checkbox label="create">创建</el-checkbox> |
|||
<el-checkbox label="edit">编辑</el-checkbox> |
|||
<el-checkbox label="delete">删除</el-checkbox> |
|||
<el-checkbox label="publish">发布</el-checkbox> |
|||
</el-checkbox-group> |
|||
</el-form-item> |
|||
<el-form-item label="订单管理权限"> |
|||
<el-checkbox-group v-model="permissionSettings.orderPermissions"> |
|||
<el-checkbox label="view">查看</el-checkbox> |
|||
<el-checkbox label="process">处理</el-checkbox> |
|||
<el-checkbox label="refund">退款</el-checkbox> |
|||
</el-checkbox-group> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" @click="savePermissionSettings">保存设置</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-tab-pane> |
|||
</el-tabs> |
|||
</el-card> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref, reactive } from 'vue' |
|||
import SideBar from '../components/SideBar.vue' |
|||
|
|||
const activeTab = ref('basic') |
|||
|
|||
// 基本设置 |
|||
const basicSettings = reactive({ |
|||
siteName: 'ElementPlus Demo', |
|||
siteUrl: 'https://example.com', |
|||
siteDescription: '这是一个使用Vue3和ElementPlus构建的示例项目', |
|||
contactEmail: 'contact@example.com', |
|||
contactPhone: '12345678901' |
|||
}) |
|||
|
|||
// 界面设置 |
|||
const interfaceSettings = reactive({ |
|||
themeColor: '#409EFF', |
|||
sidebarWidth: 200, |
|||
pageSize: 10, |
|||
showHeader: true, |
|||
showFooter: true |
|||
}) |
|||
|
|||
// 权限设置 |
|||
const permissionSettings = reactive({ |
|||
userPermissions: ['view', 'create', 'edit', 'delete'], |
|||
productPermissions: ['view', 'create', 'edit', 'delete', 'publish'], |
|||
orderPermissions: ['view', 'process', 'refund'] |
|||
}) |
|||
|
|||
// 保存设置方法 |
|||
const saveBasicSettings = () => { |
|||
// 模拟保存基本设置 |
|||
setTimeout(() => { |
|||
elMessage({ |
|||
type: 'success', |
|||
message: '基本设置保存成功!' |
|||
}) |
|||
}, 500) |
|||
} |
|||
|
|||
const saveInterfaceSettings = () => { |
|||
// 模拟保存界面设置 |
|||
setTimeout(() => { |
|||
elMessage({ |
|||
type: 'success', |
|||
message: '界面设置保存成功!' |
|||
}) |
|||
}, 500) |
|||
} |
|||
|
|||
const savePermissionSettings = () => { |
|||
// 模拟保存权限设置 |
|||
setTimeout(() => { |
|||
elMessage({ |
|||
type: 'success', |
|||
message: '权限设置保存成功!' |
|||
}) |
|||
}, 500) |
|||
} |
|||
</script> |
@ -0,0 +1,249 @@ |
|||
<template> |
|||
<div class="flex h-screen"> |
|||
<SideBar /> |
|||
<div class="flex-1 p-4 overflow-auto"> |
|||
<el-card> |
|||
<template #header> |
|||
<div class="flex justify-between items-center"> |
|||
<span>用户列表</span> |
|||
<el-button type="primary" @click="handleCreateUser">新增用户</el-button> |
|||
</div> |
|||
</template> |
|||
|
|||
<el-form :inline="true" :model="searchForm" class="mb-4"> |
|||
<el-form-item label="用户名"> |
|||
<el-input v-model="searchForm.username" placeholder="请输入用户名" clearable></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="状态"> |
|||
<el-select v-model="searchForm.status" placeholder="请选择状态" clearable> |
|||
<el-option label="启用" value="active"></el-option> |
|||
<el-option label="禁用" value="inactive"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" @click="handleSearch">搜索</el-button> |
|||
<el-button @click="resetSearch">重置</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
|
|||
<el-table :data="tableData" stripe style="width: 100%"> |
|||
<el-table-column type="selection" width="55"></el-table-column> |
|||
<el-table-column prop="id" label="ID" width="100"></el-table-column> |
|||
<el-table-column prop="username" label="用户名" width="120"></el-table-column> |
|||
<el-table-column prop="name" label="姓名" width="120"></el-table-column> |
|||
<el-table-column prop="gender" label="性别" width="80"> |
|||
<template #default="scope"> |
|||
<el-tag :type="scope.row.gender === '男' ? 'primary' : 'success'"> |
|||
{{ scope.row.gender }} |
|||
</el-tag> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="age" label="年龄" width="80"></el-table-column> |
|||
<el-table-column prop="email" label="邮箱"></el-table-column> |
|||
<el-table-column prop="status" label="状态" width="100"> |
|||
<template #default="scope"> |
|||
<el-switch |
|||
v-model="scope.row.status" |
|||
active-text="启用" |
|||
inactive-text="禁用" |
|||
@change="handleStatusChange(scope.row)" |
|||
></el-switch> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column label="操作" width="160"> |
|||
<template #default="scope"> |
|||
<el-button size="small" type="primary" @click="handleEdit(scope.row)">编辑</el-button> |
|||
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
|
|||
<el-pagination |
|||
class="mt-4 flex justify-center" |
|||
@size-change="handleSizeChange" |
|||
@current-change="handleCurrentChange" |
|||
:current-page="currentPage" |
|||
:page-sizes="[10, 20, 30, 50]" |
|||
:page-size="pageSize" |
|||
layout="total, sizes, prev, pager, next, jumper" |
|||
:total="total" |
|||
></el-pagination> |
|||
</el-card> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref, reactive, toRefs } from 'vue' |
|||
import SideBar from '../components/SideBar.vue' |
|||
|
|||
// 搜索表单 |
|||
const searchForm = reactive({ |
|||
username: '', |
|||
status: '' |
|||
}) |
|||
|
|||
// 表格数据 |
|||
const tableData = ref([ |
|||
{ id: 1, username: 'user1', name: '张三', gender: '男', age: 20, email: 'zhangsan@example.com', status: true }, |
|||
{ id: 2, username: 'user2', name: '李四', gender: '女', age: 24, email: 'lisi@example.com', status: true }, |
|||
{ id: 3, username: 'user3', name: '王五', gender: '男', age: 30, email: 'wangwu@example.com', status: false }, |
|||
{ id: 4, username: 'user4', name: '赵六', gender: '女', age: 22, email: 'zhaoliu@example.com', status: true }, |
|||
{ id: 5, username: 'user5', name: '钱七', gender: '男', age: 28, email: 'qianqi@example.com', status: true }, |
|||
{ id: 6, username: 'user6', name: '孙八', gender: '女', age: 25, email: 'sunba@example.com', status: false }, |
|||
{ id: 7, username: 'user7', name: '周九', gender: '男', age: 32, email: 'zhoujiu@example.com', status: true }, |
|||
{ id: 8, username: 'user8', name: '吴十', gender: '女', age: 27, email: 'wushi@example.com', status: true }, |
|||
]) |
|||
|
|||
// 分页 |
|||
const currentPage = ref(1) |
|||
const pageSize = ref(10) |
|||
const total = ref(100) |
|||
|
|||
// 对话框 |
|||
const dialogVisible = ref(false) |
|||
const dialogTitle = ref('') |
|||
const editForm = reactive({ |
|||
id: null, |
|||
username: '', |
|||
name: '', |
|||
gender: '男', |
|||
age: 0, |
|||
email: '', |
|||
status: true |
|||
}) |
|||
|
|||
// 表单验证规则 |
|||
const rules = reactive({ |
|||
username: [ |
|||
{ required: true, message: '请输入用户名', trigger: 'blur' }, |
|||
{ min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' } |
|||
], |
|||
name: [ |
|||
{ required: true, message: '请输入姓名', trigger: 'blur' } |
|||
], |
|||
email: [ |
|||
{ required: true, message: '请输入邮箱', trigger: 'blur' }, |
|||
{ type: 'email', message: '请输入正确的邮箱格式', trigger: ['blur', 'change'] } |
|||
] |
|||
}) |
|||
|
|||
// 表单引用 |
|||
const editFormRef = ref(null) |
|||
|
|||
// 搜索方法 |
|||
const handleSearch = () => { |
|||
console.log('搜索条件:', searchForm) |
|||
// 这里可以添加搜索逻辑 |
|||
} |
|||
|
|||
const resetSearch = () => { |
|||
searchForm.username = '' |
|||
searchForm.status = '' |
|||
} |
|||
|
|||
// 表格操作 |
|||
const handleEdit = (row) => { |
|||
// 复制数据到编辑表单 |
|||
Object.assign(editForm, row) |
|||
dialogTitle.value = '编辑用户' |
|||
dialogVisible.value = true |
|||
} |
|||
|
|||
const handleDelete = (row) => { |
|||
elMessageBox.confirm( |
|||
'确定要删除该用户吗?', |
|||
'提示', |
|||
{ |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning' |
|||
} |
|||
).then(() => { |
|||
// 从表格数据中删除 |
|||
const index = tableData.value.findIndex(item => item.id === row.id) |
|||
if (index !== -1) { |
|||
tableData.value.splice(index, 1) |
|||
elMessage({ |
|||
type: 'success', |
|||
message: '删除成功!' |
|||
}) |
|||
} |
|||
}).catch(() => { |
|||
elMessage({ |
|||
type: 'info', |
|||
message: '已取消删除' |
|||
}) |
|||
}) |
|||
} |
|||
|
|||
const handleStatusChange = (row) => { |
|||
const statusText = row.status ? '启用' : '禁用' |
|||
elMessage({ |
|||
type: 'success', |
|||
message: `用户 ${row.username} 已${statusText}` |
|||
}) |
|||
} |
|||
|
|||
// 分页事件处理 |
|||
const handleSizeChange = (newSize) => { |
|||
pageSize.value = newSize |
|||
console.log('每页条数:', newSize) |
|||
} |
|||
|
|||
const handleCurrentChange = (newPage) => { |
|||
currentPage.value = newPage |
|||
console.log('当前页码:', newPage) |
|||
} |
|||
|
|||
// 创建用户 |
|||
const handleCreateUser = () => { |
|||
// 清空表单 |
|||
Object.keys(editForm).forEach(key => { |
|||
if (key === 'id') { |
|||
editForm[key] = null |
|||
} else if (key === 'status') { |
|||
editForm[key] = true |
|||
} else if (key === 'gender') { |
|||
editForm[key] = '男' |
|||
} else { |
|||
editForm[key] = '' |
|||
} |
|||
}) |
|||
|
|||
dialogTitle.value = '新增用户' |
|||
dialogVisible.value = true |
|||
} |
|||
|
|||
// 保存用户 |
|||
const saveUser = () => { |
|||
editFormRef.value.validate((valid) => { |
|||
if (valid) { |
|||
// 模拟保存操作 |
|||
setTimeout(() => { |
|||
dialogVisible.value = false |
|||
elMessage({ |
|||
type: 'success', |
|||
message: dialogTitle.value === '新增用户' ? '创建成功!' : '更新成功!' |
|||
}) |
|||
|
|||
// 更新表格数据 |
|||
if (editForm.id) { |
|||
// 更新现有用户 |
|||
const index = tableData.value.findIndex(item => item.id === editForm.id) |
|||
if (index !== -1) { |
|||
tableData.value.splice(index, 1, { ...editForm }) |
|||
} |
|||
} else { |
|||
// 创建新用户 |
|||
const newId = Math.max(...tableData.value.map(item => item.id)) + 1 |
|||
tableData.value.unshift({ ...editForm, id: newId }) |
|||
} |
|||
}, 500) |
|||
} else { |
|||
console.log('验证失败') |
|||
return false |
|||
} |
|||
}) |
|||
} |
|||
</script> |
@ -0,0 +1,35 @@ |
|||
import {createRouter, createWebHistory} from 'vue-router' |
|||
import HomeView from "../pages/HomeView.vue"; |
|||
import ProductView from "../pages/ProductView.vue"; |
|||
import UserView from "../pages/UserView.vue"; |
|||
import SettingView from "../pages/SettingView.vue"; |
|||
|
|||
|
|||
|
|||
const router = createRouter({ |
|||
history: createWebHistory(import.meta.env.BASE_URL), |
|||
routes: [ |
|||
{ |
|||
path: '/', |
|||
name: 'home', |
|||
component: HomeView |
|||
}, |
|||
{ |
|||
path: '/product', |
|||
name: 'product', |
|||
component: ProductView |
|||
}, |
|||
{ |
|||
path: '/user', |
|||
name: 'user', |
|||
component: UserView |
|||
}, |
|||
{ |
|||
path: '/setting', |
|||
name: 'setting', |
|||
component: SettingView |
|||
} |
|||
] |
|||
}) |
|||
|
|||
export default router |
@ -0,0 +1,33 @@ |
|||
//导入axios
|
|||
import axios from "axios" |
|||
|
|||
//axios.create创建一个axios实例
|
|||
//我们给这个实例编写配置,后端所有通过这个实例发送请求,都受这个配置约束。
|
|||
const $http=axios.create({ |
|||
baseURL:"http://8080/", |
|||
timeout:1000 |
|||
}); |
|||
|
|||
|
|||
|
|||
// 添加请求拦截器
|
|||
$http.interceptors.request.use(function (config) { |
|||
// 在发送请求之前做些什么
|
|||
return config; |
|||
}, function (error) { |
|||
// 对请求错误做些什么
|
|||
return Promise.reject(error); |
|||
}); |
|||
|
|||
|
|||
|
|||
// 添加响应拦截器
|
|||
$http.interceptors.response.use(function (response) { |
|||
// 对响应数据做点什么
|
|||
return response.data; |
|||
}, function (error) { |
|||
// 对响应错误做点什么
|
|||
return Promise.reject(error); |
|||
}); |
|||
|
|||
export default $http; |
@ -0,0 +1,3 @@ |
|||
import $http from "./http" |
|||
|
|||
export const getData=$http.get("/posts"); |
@ -0,0 +1 @@ |
|||
/// <reference types="vite/client" />
|
@ -0,0 +1,15 @@ |
|||
{ |
|||
"extends": "@vue/tsconfig/tsconfig.dom.json", |
|||
"compilerOptions": { |
|||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", |
|||
|
|||
/* Linting */ |
|||
"strict": true, |
|||
"noUnusedLocals": true, |
|||
"noUnusedParameters": true, |
|||
"erasableSyntaxOnly": true, |
|||
"noFallthroughCasesInSwitch": true, |
|||
"noUncheckedSideEffectImports": true |
|||
}, |
|||
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] |
|||
} |
@ -0,0 +1,9 @@ |
|||
{ |
|||
"files": [], |
|||
"references": [ |
|||
{ "path": "./tsconfig.app.json" }, |
|||
{ "path": "./tsconfig.node.json" } |
|||
|
|||
], |
|||
|
|||
} |
@ -0,0 +1,25 @@ |
|||
{ |
|||
"compilerOptions": { |
|||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", |
|||
"target": "ES2022", |
|||
"lib": ["ES2025"], |
|||
"module": "ESNext", |
|||
"skipLibCheck": true, |
|||
|
|||
/* Bundler mode */ |
|||
"moduleResolution": "bundler", |
|||
"allowImportingTsExtensions": true, |
|||
"verbatimModuleSyntax": true, |
|||
"moduleDetection": "force", |
|||
"noEmit": true, |
|||
|
|||
/* Linting */ |
|||
"strict": true, |
|||
"noUnusedLocals": true, |
|||
"noUnusedParameters": true, |
|||
"erasableSyntaxOnly": true, |
|||
"noFallthroughCasesInSwitch": true, |
|||
"noUncheckedSideEffectImports": true |
|||
}, |
|||
"include": ["vite.config.ts"] |
|||
} |
@ -0,0 +1,7 @@ |
|||
import { defineConfig } from 'vite' |
|||
import vue from '@vitejs/plugin-vue' |
|||
|
|||
// https://vite.dev/config/
|
|||
export default defineConfig({ |
|||
plugins: [vue()], |
|||
}) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue