This commit is contained in:
april 2023-06-19 09:31:52 +08:00
commit 610f138abb
14 changed files with 103 additions and 62 deletions

View File

@ -1,6 +1,25 @@
# 2.4.0 (2023/6/17)
### ✨ feat
- 新增组件标签输入框author by [april-tong](https://april-tong.com/)
- 新增组件签名author by [april-tong](https://april-tong.com/)
- 新增组件表格author by [april-tong](https://april-tong.com/)
- Echarts 图表添加下载功能 author by [april-tong](https://april-tong.com/)
### 🔄 refactor
- 限制包管理器为 pnpm 和 node 版本16+
- 自定义组件自动导入配置
- 搜索框样式写法优化
### 🐛 fix
- 用户导入的部门回显成数字问题修复
### ⬆️ chore
- element-plus 版本升级 2.3.5 → 2.3.6
# 2.3.1 (2023/5/21)
### ✂️ refactor
### 🔄 refactor
- 组件示例文件名称优化
# 2.2.2 (2023/5/11)
@ -16,7 +35,7 @@
- vue 版本升级 3.2.45 → 3.3.1 ([CHANGELOG](https://github.com/vuejs/core/blob/main/CHANGELOG.md))
- vite 版本升级 4.3.1 → 4.3.5
### ✂️ refactor
### 🔄 refactor
- 使用 vue 3.3 版本新特性 `defineOptions``setup` 定义组件名称,移除重复的 `script` 标签
# 2.2.2 (2023/5/11)

View File

@ -1,7 +1,7 @@
{
"name": "vue3-element-admin",
"private": true,
"version": "2.3.1",
"version": "2.4.0",
"type": "module",
"scripts": {
"preinstall": "npx only-allow pnpm",

View File

@ -3,14 +3,14 @@
@import "./dark";
.app-container {
margin: 20px;
.search {
padding: 18px 0 0 10px;
margin-bottom: 10px;
background-color: var(--el-bg-color-overlay);
border: 1px solid var(--el-border-color-light);
border-radius: 4px;
box-shadow: var(--el-box-shadow-light);
}
padding: 10px;
}
.search-container {
padding: 18px 0 0 10px;
margin-bottom: 10px;
background-color: var(--el-bg-color-overlay);
border: 1px solid var(--el-border-color-light);
border-radius: 4px;
box-shadow: var(--el-box-shadow-light);
}

View File

@ -9,6 +9,8 @@ export {};
declare module "@vue/runtime-core" {
export interface GlobalComponents {
AppMain: typeof import("./../layout/components/AppMain.vue")["default"];
BarChart: typeof import("./../views/dashboard/components/BarChart.vue")["default"];
Breadcrumb: typeof import("./../components/Breadcrumb/index.vue")["default"];
ElAlert: typeof import("element-plus/es")["ElAlert"];
ElBreadcrumb: typeof import("element-plus/es")["ElBreadcrumb"];
@ -46,9 +48,11 @@ declare module "@vue/runtime-core" {
ElTree: typeof import("element-plus/es")["ElTree"];
ElTreeSelect: typeof import("element-plus/es")["ElTreeSelect"];
ElUpload: typeof import("element-plus/es")["ElUpload"];
FunnelChart: typeof import("./../views/dashboard/components/FunnelChart.vue")["default"];
GithubCorner: typeof import("./../components/GithubCorner/index.vue")["default"];
Hamburger: typeof import("./../components/Hamburger/index.vue")["default"];
IconSelect: typeof import("./../components/IconSelect/index.vue")["default"];
IEpArrowDown: typeof import("~icons/ep/arrow-down")["default"];
IEpCaretBottom: typeof import("~icons/ep/caret-bottom")["default"];
IEpCaretTop: typeof import("~icons/ep/caret-top")["default"];
IEpClose: typeof import("~icons/ep/close")["default"];
@ -62,18 +66,30 @@ declare module "@vue/runtime-core" {
IEpRefreshLeft: typeof import("~icons/ep/refresh-left")["default"];
IEpSearch: typeof import("~icons/ep/search")["default"];
IEpSetting: typeof import("~icons/ep/setting")["default"];
IEpSortDown: typeof import("~icons/ep/sort-down")["default"];
IEpSortUp: typeof import("~icons/ep/sort-up")["default"];
IEpTop: typeof import("~icons/ep/top")["default"];
IEpUploadFilled: typeof import("~icons/ep/upload-filled")["default"];
LangSelect: typeof import("./../components/LangSelect/index.vue")["default"];
Link: typeof import("./../layout/components/Sidebar/Link.vue")["default"];
Logo: typeof import("./../layout/components/Sidebar/Logo.vue")["default"];
MultiUpload: typeof import("./../components/Upload/MultiUpload.vue")["default"];
Navbar: typeof import("./../layout/components/Navbar.vue")["default"];
Pagination: typeof import("./../components/Pagination/index.vue")["default"];
PieChart: typeof import("./../views/dashboard/components/PieChart.vue")["default"];
RadarChart: typeof import("./../views/dashboard/components/RadarChart.vue")["default"];
RightPanel: typeof import("./../components/RightPanel/index.vue")["default"];
RouterLink: typeof import("vue-router")["RouterLink"];
RouterView: typeof import("vue-router")["RouterView"];
ScrollPane: typeof import("./../layout/components/TagsView/ScrollPane.vue")["default"];
Settings: typeof import("./../layout/components/Settings/index.vue")["default"];
Sidebar: typeof import("./../layout/components/Sidebar/index.vue")["default"];
SidebarItem: typeof import("./../layout/components/Sidebar/SidebarItem.vue")["default"];
SingleUpload: typeof import("./../components/Upload/SingleUpload.vue")["default"];
SizeSelect: typeof import("./../components/SizeSelect/index.vue")["default"];
SvgIcon: typeof import("./../components/SvgIcon/index.vue")["default"];
TagInput: typeof import("./../components/TagInput/index.vue")["default"];
TagsView: typeof import("./../layout/components/TagsView/index.vue")["default"];
WangEditor: typeof import("./../components/WangEditor/index.vue")["default"];
}
export interface ComponentCustomProperties {

View File

@ -8,12 +8,6 @@ defineOptions({
import { useUserStore } from "@/store/modules/user";
import { useTransition, TransitionPresets } from "@vueuse/core";
import GithubCorner from "@/components/GithubCorner/index.vue";
import SvgIcon from "@/components/SvgIcon/index.vue";
import BarChart from "./components/BarChart.vue";
import PieChart from "./components/PieChart.vue";
import RadarChart from "./components/RadarChart.vue";
const userStore = useUserStore();
const date: Date = new Date();
@ -90,26 +84,26 @@ orderCount.value = 2000;
{{ greetings }}
</div>
<div class="space-x-2 flex items-center">
<div class="space-x-2 flex items-center justify-end">
<el-link
target="_blank"
type="danger"
href="https://blog.csdn.net/u013737132/article/details/130191394"
>官方0到1教程</el-link
>💥官方从零到一文档</el-link
>
<el-divider direction="vertical" />
<el-link
target="_blank"
type="success"
href="https://gitee.com/youlaiorg/vue3-element-admin"
>Gitee源码</el-link
href="https://gitee.com/youlaiorg"
>Gitee</el-link
>
<el-divider direction="vertical" />
<el-link
target="_blank"
type="primary"
href="https://github.com/youlaitech/vue3-element-admin"
>GitHub源码
href="https://github.com/youlaitech"
>GitHub
</el-link>
</div>
</div>
@ -160,7 +154,7 @@ orderCount.value = 2000;
</div>
<div class="flex flex-col space-y-3">
<div class="text-[var(--el-text-color-secondary)]">收入金额</div>
<div class="text-lg">
<div class="text-lg text-right">
{{ Math.round(amountOutput) }}
</div>
</div>

View File

@ -14,6 +14,14 @@
.app-container {
display: flex;
flex-direction: column;
height: calc(100vh - 124px);
/* 84 = navbar + tags-view = 50 + 34 */
height: calc(100vh - 50px);
}
.hasTagsView {
.app-container {
height: calc(100vh - 84px);
}
}
</style>

View File

@ -86,7 +86,7 @@ onMounted(() => {});
>
<div>
<div class="search">
<div class="search-container">
<el-form :inline="true">
<el-form-item> <el-input v-model="inputVal" /></el-form-item>
<el-form-item

View File

@ -181,7 +181,7 @@ onMounted(() => {
</script>
<template>
<div class="app-container">
<div class="search">
<div class="search-container">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="关键字" prop="keywords">
<el-input

View File

@ -196,7 +196,7 @@ onMounted(() => {
<template>
<div class="app-container">
<div class="search">
<div class="search-container">
<!-- 搜索表单 -->
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="关键字" prop="name">

View File

@ -194,7 +194,7 @@ onMounted(() => {
<template>
<div class="app-container">
<div class="search">
<div class="search-container">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="关键字" prop="name">
<el-input

View File

@ -83,8 +83,6 @@ function resetQuery() {
/**
* 行点击事件
*
* @param row
*/
function onRowClick(row: MenuVO) {
selectedRowMenuId.value = row.id;
@ -130,7 +128,7 @@ function onMenuTypeChange() {
}
/**
* 菜单提交
* 菜单保存提交
*/
function submitForm() {
menuFormRef.value.validate((isValid: boolean) => {
@ -155,6 +153,7 @@ function submitForm() {
/**
* 删除菜单
* @param menuId 菜单ID
*/
function handleDelete(menuId: number) {
if (!menuId) {
@ -198,6 +197,7 @@ function resetForm() {
formData.perm = undefined;
formData.component = undefined;
formData.path = undefined;
formData.redirect = undefined;
}
onMounted(() => {
@ -207,7 +207,7 @@ onMounted(() => {
<template>
<div class="app-container">
<div class="search">
<div class="search-container">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="关键字" prop="keywords">
<el-input

View File

@ -243,7 +243,7 @@ onMounted(() => {
<template>
<div class="app-container">
<div class="search">
<div class="search-container">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item prop="keywords" label="关键字">
<el-input

View File

@ -73,7 +73,11 @@ const importDialog = reactive<DialogOption>({
title: "用户导入",
visible: false,
});
const importDeptId = ref<number>(0);
/**
* 导入选择的部门ID
*/
const importDeptId = ref<number>();
const excelFile = ref<File>();
const excelFilelist = ref<File[]>([]);
@ -191,9 +195,7 @@ function resetPassword(row: { [key: string]: any }) {
}
/**
* 打开弹窗
*
* @param userId 用户ID
* 打开用户弹窗
*/
async function openDialog(userId?: number) {
await getDeptOptions();
@ -210,7 +212,7 @@ async function openDialog(userId?: number) {
}
/**
* 关闭用户弹窗
* 关闭弹窗
*/
function closeDialog() {
dialog.visible = false;
@ -310,11 +312,11 @@ function downloadTemplate() {
}
/**
* 导入弹窗
* 打开导入弹窗
*/
async function openImportDialog() {
await getDeptOptions();
await getRoleOptions();
importDeptId.value = undefined;
importDialog.visible = true;
}
@ -334,7 +336,7 @@ function handleExcelChange(file: UploadFile) {
}
/**
* 导入用户
* 导入用户提交
*/
function handleUserImport() {
if (importDeptId.value) {
@ -412,7 +414,7 @@ onMounted(() => {
</el-col>
<el-col :lg="20" :xs="24">
<div class="search">
<div class="search-container">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="关键字" prop="keywords">
<el-input

View File

@ -53,39 +53,41 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
},
plugins: [
vue(),
UnoCSS({
/* options */
}),
UnoCSS({}),
AutoImport({
// 自动导入 Vue 相关函数ref, reactive, toRef 等
imports: ["vue", "@vueuse/core"],
eslintrc: {
enabled: false, // Default `false`
filepath: "./.eslintrc-auto-import.json", // Default `./.eslintrc-auto-import.json`
globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
enabled: false,
filepath: "./.eslintrc-auto-import.json",
globalsPropValue: true,
},
resolvers: [
// 自动导入 Element Plus 相关函数ElMessage, ElMessageBox... (带样式)
ElementPlusResolver(),
// 自动导入图标组件
IconsResolver({}),
],
vueTemplate: true, // 是否在 vue 模板中自动导入
dts: false, // 关闭自动生成
//dts: path.resolve(pathSrc, "types", "auto-imports.d.ts"), // 自动导入组件类型声明文件位置,默认根目录
vueTemplate: true,
// 配置文件生成位置(false:关闭自动生成)
dts: false,
// dts: "src/types/auto-imports.d.ts",
}),
Components({
resolvers: [
// 自动注册图标组件
IconsResolver({
enabledCollections: ["ep"], //@iconify-json/ep 是 Element Plus 的图标库
}),
// 自动导入 Element Plus 组件
ElementPlusResolver(),
// 自动导入图标组件
IconsResolver({
// @iconify-json/ep 是 Element Plus 的图标库
enabledCollections: ["ep"],
}),
],
dts: false, // 关闭自动生成
// dts: path.resolve(pathSrc, "types", "components.d.ts"), // 自动导入组件类型声明文件位置,默认根目录
// 指定自定义组件位置(默认:src/components)
dirs: ["src/**/components"],
// 配置文件位置(false:关闭自动生成)
dts: false,
// dts: "src/types/components.d.ts",
}),
Icons({
@ -100,7 +102,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
symbolId: "icon-[dir]-[name]",
}),
],
// 预加载项目必需的组件
optimizeDeps: {
include: [
"vue",