Merge branch 'master' of https://github.com/youlaitech/vue3-element-admin
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<el-card shadow="never" class="table-container">
|
||||
<!-- 表格工具栏 -->
|
||||
<div class="flex-x-between mb-[10px]">
|
||||
<!-- 左侧工具栏 -->
|
||||
<div>
|
||||
<!-- 表格左上方工具栏 -->
|
||||
<template v-for="item in contentConfig.toolbar" :key="item">
|
||||
<template v-if="typeof item === 'string'">
|
||||
<!-- 新增 -->
|
||||
@@ -64,42 +65,47 @@
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- 表格右上方工具栏 -->
|
||||
<!-- 右侧工具栏 -->
|
||||
<div>
|
||||
<el-icon class="cursor-pointer" @click="handleToolbar('refresh')">
|
||||
<i-ep-refresh />
|
||||
</el-icon>
|
||||
|
||||
<!-- 列设置 -->
|
||||
<el-popover placement="bottom" trigger="click">
|
||||
<template #reference>
|
||||
<el-icon class="cursor-pointer ml-2">
|
||||
<i-ep-setting />
|
||||
<template v-for="item in defaultToolbar" :key="item">
|
||||
<template v-if="item === 'refresh'">
|
||||
<el-icon class="cursor-pointer ml-2" @click="handleToolbar(item)">
|
||||
<i-ep-refresh />
|
||||
</el-icon>
|
||||
</template>
|
||||
|
||||
<el-checkbox
|
||||
v-model="columnSetting.checkAll"
|
||||
:indeterminate="columnSetting.isIndeterminate"
|
||||
@change="handleCheckAllChange"
|
||||
>
|
||||
全选
|
||||
</el-checkbox>
|
||||
<template v-else-if="item === 'filter'">
|
||||
<!-- 列设置 -->
|
||||
<el-popover placement="bottom" trigger="click">
|
||||
<template #reference>
|
||||
<el-icon class="cursor-pointer ml-2">
|
||||
<i-ep-setting />
|
||||
</el-icon>
|
||||
</template>
|
||||
|
||||
<el-checkbox-group
|
||||
v-model="columnSetting.checkedCols"
|
||||
@change="handleCheckedColumnsChange"
|
||||
>
|
||||
<div v-for="col in contentConfig.cols" :key="col.label">
|
||||
<el-checkbox
|
||||
v-if="col.label"
|
||||
:value="col.label"
|
||||
:label="col.label"
|
||||
/>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
</el-popover>
|
||||
v-model="columnSetting.checkAll"
|
||||
:indeterminate="columnSetting.isIndeterminate"
|
||||
@change="handleCheckAllChange"
|
||||
>
|
||||
全选
|
||||
</el-checkbox>
|
||||
|
||||
<el-checkbox-group
|
||||
v-model="columnSetting.checkedCols"
|
||||
@change="handleCheckedColumnsChange"
|
||||
>
|
||||
<div v-for="col in contentConfig.cols" :key="col.label">
|
||||
<el-checkbox
|
||||
v-if="col.label"
|
||||
:value="col.label"
|
||||
:label="col.label"
|
||||
/>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
</el-popover>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 列表 -->
|
||||
@@ -266,9 +272,8 @@ export interface IContentConfig<T = any> {
|
||||
exportAction?: (queryParams: T) => Promise<any>;
|
||||
// 主键名(默认为id)
|
||||
pk?: string;
|
||||
// 表格工具栏(默认支持refresh,add,delete,export,也可自定义)
|
||||
// 表格工具栏(默认支持add,delete,export,也可自定义)
|
||||
toolbar: (
|
||||
| "refresh"
|
||||
| "add"
|
||||
| "delete"
|
||||
| "export"
|
||||
@@ -279,6 +284,8 @@ export interface IContentConfig<T = any> {
|
||||
text: string;
|
||||
}
|
||||
)[];
|
||||
// 表格工具栏右侧图标
|
||||
defaultToolbar?: ("refresh" | "filter")[];
|
||||
// table组件列属性(额外的属性templet,operat,slotName)
|
||||
cols: IObject[];
|
||||
}
|
||||
@@ -298,6 +305,11 @@ defineExpose({ fetchPageData, exportPageData });
|
||||
|
||||
// 主键
|
||||
const pk = props.contentConfig.pk ?? "id";
|
||||
// 表格工具栏右侧图标
|
||||
const defaultToolbar = props.contentConfig.defaultToolbar ?? [
|
||||
"refresh",
|
||||
"filter",
|
||||
];
|
||||
// 加载状态
|
||||
const loading = ref(false);
|
||||
// 删除ID集合 用于批量删除
|
||||
|
||||
@@ -1,171 +1,71 @@
|
||||
<template>
|
||||
<div class="search-container" v-hasPerm="[`${searchConfig.pageName}:query`]">
|
||||
<el-form ref="queryFormRef" :model="queryParams">
|
||||
<el-row :gutter="20">
|
||||
<template
|
||||
v-if="isExpand || searchConfig.formItems.length <= showNumber"
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<template
|
||||
v-for="(item, index) in searchConfig.formItems"
|
||||
:key="item.prop"
|
||||
>
|
||||
<el-form-item
|
||||
v-show="isExpand ? true : index < showNumber"
|
||||
:label="item.label"
|
||||
:prop="item.prop"
|
||||
>
|
||||
<el-col
|
||||
v-bind="colSpans"
|
||||
v-for="item in searchConfig.formItems"
|
||||
:key="item.prop"
|
||||
>
|
||||
<el-form-item :label="item.label" :prop="item.prop">
|
||||
<!-- Input 输入框 -->
|
||||
<template v-if="item.type === 'input'">
|
||||
<template v-if="item.attrs?.type === 'number'">
|
||||
<el-input
|
||||
v-model.number="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-input
|
||||
v-model="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</template>
|
||||
<!-- Input 输入框 -->
|
||||
<template v-if="item.type === 'input' || item.type === undefined">
|
||||
<el-input
|
||||
v-model="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</template>
|
||||
<!-- Select 选择器 -->
|
||||
<template v-else-if="item.type === 'select'">
|
||||
<el-select v-model="queryParams[item.prop]" v-bind="item.attrs">
|
||||
<template v-for="option in item.options" :key="option.value">
|
||||
<el-option :label="option.label" :value="option.value" />
|
||||
</template>
|
||||
<!-- Select 选择器 -->
|
||||
<template v-else-if="item.type === 'select'">
|
||||
<el-select v-model="queryParams[item.prop]" v-bind="item.attrs">
|
||||
<template v-for="option in item.options" :key="option.value">
|
||||
<el-option :label="option.label" :value="option.value" />
|
||||
</template>
|
||||
</el-select>
|
||||
</template>
|
||||
<!-- TreeSelect 树形选择 -->
|
||||
<template v-else-if="item.type === 'tree-select'">
|
||||
<el-tree-select
|
||||
v-model="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
/>
|
||||
</template>
|
||||
<!-- DatePicker 日期选择器 -->
|
||||
<template v-else-if="item.type === 'date-picker'">
|
||||
<el-date-picker
|
||||
v-model="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
/>
|
||||
</template>
|
||||
<!-- Input 输入框 -->
|
||||
<template v-else>
|
||||
<template v-if="item.attrs?.type === 'number'">
|
||||
<el-input
|
||||
v-model.number="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-input
|
||||
v-model="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<el-col
|
||||
v-bind="colSpans"
|
||||
v-for="item in searchConfig.formItems.slice(0, showNumber)"
|
||||
:key="item.prop"
|
||||
>
|
||||
<el-form-item :label="item.label" :prop="item.prop">
|
||||
<!-- Input 输入框 -->
|
||||
<template v-if="item.type === 'input'">
|
||||
<template v-if="item.attrs?.type === 'number'">
|
||||
<el-input
|
||||
v-model.number="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-input
|
||||
v-model="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
<!-- Select 选择器 -->
|
||||
<template v-else-if="item.type === 'select'">
|
||||
<el-select v-model="queryParams[item.prop]" v-bind="item.attrs">
|
||||
<template v-for="option in item.options" :key="option.value">
|
||||
<el-option :label="option.label" :value="option.value" />
|
||||
</template>
|
||||
</el-select>
|
||||
</template>
|
||||
<!-- TreeSelect 树形选择 -->
|
||||
<template v-else-if="item.type === 'tree-select'">
|
||||
<el-tree-select
|
||||
v-model="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
/>
|
||||
</template>
|
||||
<!-- DatePicker 日期选择器 -->
|
||||
<template v-else-if="item.type === 'date-picker'">
|
||||
<el-date-picker
|
||||
v-model="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
/>
|
||||
</template>
|
||||
<!-- Input 输入框 -->
|
||||
<template v-else>
|
||||
<template v-if="item.attrs?.type === 'number'">
|
||||
<el-input
|
||||
v-model.number="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-input
|
||||
v-model="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<div class="flex flex-auto items-start justify-end pr-5">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="search" @click="handleQuery">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button icon="refresh" @click="handleReset">重置</el-button>
|
||||
|
||||
<el-link
|
||||
v-if="isExpandable && searchConfig.formItems.length > showNumber"
|
||||
@click="isExpand = !isExpand"
|
||||
class="ml-2"
|
||||
type="primary"
|
||||
:underline="false"
|
||||
>
|
||||
{{ isExpand ? "收起" : "展开" }}
|
||||
<i-ep-arrow-up v-if="isExpand" />
|
||||
<i-ep-arrow-down v-else />
|
||||
</el-link>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-row>
|
||||
</el-select>
|
||||
</template>
|
||||
<!-- TreeSelect 树形选择 -->
|
||||
<template v-else-if="item.type === 'tree-select'">
|
||||
<el-tree-select
|
||||
v-model="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
/>
|
||||
</template>
|
||||
<!-- DatePicker 日期选择器 -->
|
||||
<template v-else-if="item.type === 'date-picker'">
|
||||
<el-date-picker
|
||||
v-model="queryParams[item.prop]"
|
||||
v-bind="item.attrs"
|
||||
/>
|
||||
</template>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="search" @click="handleQuery">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button icon="refresh" @click="handleReset">重置</el-button>
|
||||
<!-- 展开/收起 -->
|
||||
<el-link
|
||||
v-if="isExpandable && searchConfig.formItems.length > showNumber"
|
||||
class="ml-2"
|
||||
type="primary"
|
||||
:underline="false"
|
||||
@click="isExpand = !isExpand"
|
||||
>
|
||||
<template v-if="isExpand"> 收起<i-ep-arrow-up /> </template>
|
||||
<template v-else> 展开<i-ep-arrow-down /> </template>
|
||||
</el-link>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue";
|
||||
import type { ElForm } from "element-plus";
|
||||
import type { FormInstance } from "element-plus";
|
||||
import { reactive, ref } from "vue";
|
||||
|
||||
// 对象类型
|
||||
type IObject = Record<string, any>;
|
||||
@@ -197,29 +97,6 @@ interface IProps {
|
||||
searchConfig: ISearchConfig;
|
||||
}
|
||||
const props = defineProps<IProps>();
|
||||
|
||||
// 是否可展开/收缩
|
||||
const isExpandable = ref(props.searchConfig.isExpandable);
|
||||
// 是否展开
|
||||
const isExpand = ref(false);
|
||||
|
||||
// 表单项展示数量,若可展开,超出展示数量的表单项隐藏
|
||||
const showNumber = computed(() => {
|
||||
if (isExpandable.value === true) {
|
||||
return props.searchConfig.showNumber ?? 3;
|
||||
} else {
|
||||
return props.searchConfig.formItems.length;
|
||||
}
|
||||
});
|
||||
// 表单项栅格列数配置
|
||||
const colSpans = {
|
||||
xs: 24,
|
||||
sm: 12,
|
||||
md: 8,
|
||||
lg: 6,
|
||||
xl: 4,
|
||||
};
|
||||
|
||||
// 自定义事件
|
||||
const emit = defineEmits<{
|
||||
queryClick: [queryParams: IObject];
|
||||
@@ -228,7 +105,20 @@ const emit = defineEmits<{
|
||||
// 暴露的属性和方法
|
||||
defineExpose({ getQueryParams });
|
||||
|
||||
const queryFormRef = ref<InstanceType<typeof ElForm>>();
|
||||
// 是否可展开/收缩
|
||||
const isExpandable = ref(props.searchConfig.isExpandable ?? true);
|
||||
// 是否已展开
|
||||
const isExpand = ref(false);
|
||||
// 表单项展示数量,若可展开,超出展示数量的表单项隐藏
|
||||
const showNumber = computed(() => {
|
||||
if (isExpandable.value === true) {
|
||||
return props.searchConfig.showNumber ?? 3;
|
||||
} else {
|
||||
return props.searchConfig.formItems.length;
|
||||
}
|
||||
});
|
||||
|
||||
const queryFormRef = ref<FormInstance>();
|
||||
// 搜索表单数据
|
||||
const queryParams = reactive<IObject>({});
|
||||
for (const item of props.searchConfig.formItems) {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
v-model="settingsVisible"
|
||||
size="300"
|
||||
:title="$t('settings.project')"
|
||||
:lockScroll="false"
|
||||
>
|
||||
<el-divider>{{ $t("settings.theme") }}</el-divider>
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ const contentConfig: IContentConfig<UserQuery> = {
|
||||
exportAction: UserAPI.export,
|
||||
pk: "id",
|
||||
toolbar: [
|
||||
"refresh",
|
||||
"add",
|
||||
"delete",
|
||||
"export",
|
||||
|
||||
@@ -11,7 +11,7 @@ const searchConfig: ISearchConfig = {
|
||||
placeholder: "用户名/昵称/手机号",
|
||||
clearable: true,
|
||||
style: {
|
||||
width: "80%",
|
||||
width: "200px",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -42,7 +42,7 @@ const searchConfig: ISearchConfig = {
|
||||
"render-after-expand": false,
|
||||
clearable: true,
|
||||
style: {
|
||||
width: "80%",
|
||||
width: "150px",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -54,7 +54,7 @@ const searchConfig: ISearchConfig = {
|
||||
placeholder: "全部",
|
||||
clearable: true,
|
||||
style: {
|
||||
width: "60%",
|
||||
width: "100px",
|
||||
},
|
||||
},
|
||||
options: [
|
||||
@@ -73,12 +73,11 @@ const searchConfig: ISearchConfig = {
|
||||
"end-placeholder": "截止时间",
|
||||
"value-format": "YYYY-MM-DD",
|
||||
style: {
|
||||
width: "60%",
|
||||
width: "240px",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
isExpandable: true,
|
||||
};
|
||||
|
||||
export default searchConfig;
|
||||
|
||||
Reference in New Issue
Block a user