vue3.0+ts+antdesginVue 表格上方搜索条件(新增 搜索 重置 收起展开)的封装
话不多说 先上效果:
表格条件搜索封装
封装代码:
searchForm组件 (src/components/searchForm/index.vue)
<template>
<div class="gl-serachForm" id="serch-card">
<div
v-if="isShowForm"
:class="['gl-search-top', { 'gl-search-top-open': isOpen }]"
>
<div class="search-form-title">
<slot name="search-title"></slot>
<div class="search-button">
<a-button type="primary" @click="addMethods">
<template #icon>
<PlusOutlined />
</template>
{{ addBtnName }}
</a-button>
</div>
</div>
<a-divider />
<div class="form-an-btn">
<span
style="width: calc(100% - 215px); display: inline-block"
class="gl-search-form-norepat"
>
<a-row :gutter="[6, 12]">
<a-col
v-for="form in num"
:key="`search${form}`"
:xs="12"
:md="12"
:lg="8"
:xxl="6"
>
<slot :name="`form_${form}`" :id="`slot${form}`"></slot>
</a-col>
</a-row>
</span>
</div>
<span class="search-btn">
<a-button type="primary" @click="$emit('searchTable')">搜索</a-button>
<a-button style="margin-left: 15px" @click="$emit('resetForm')"
>重置</a-button
>
<span v-show="isShowMore">
<span class="split-line"></span>
<span
@click="setOpenStatu"
:class="[
'gl-search-open-close',
'gl-font-color',
{ 'gl-search-open': isOpen },
{ 'gl-search-close': isOpen === false },
]"
>
{{ isOpen ? "收起" : "展开" }}更多
<DoubleRightOutlined class="icon" />
</span>
</span>
</span>
</div>
</div>
</template>
<script lang="ts">
import { ref, defineComponent, nextTick, computed, onMounted } from "vue";
import { DoubleRightOutlined, PlusOutlined } from "@ant-design/icons-vue";
export default defineComponent({
components: {
DoubleRightOutlined,
PlusOutlined,
},
props: {
// 表单数量
num: {
type: Number,
default: 0,
},
// 是否展示搜索表单
isShowForm: {
type: Boolean,
default: () => {
return true;
},
},
addBtnName: {
type: String,
default: "新增",
},
// propTypes.bool.def(true)
},
setup(props, { emit }) {
const bodyWidth = ref(0);
// 是否为展开状态
const isOpen = ref(false);
// 初始动画状态
const isAnim = ref(false);
onMounted(async () => {
await nextTick(() => {
setTableHeight();
});
setBodyWidth();
window.onresize = () => {
setTableHeight();
setBodyWidth();
};
});
let isShowMore = computed(() => {
let bodyWidth_ = bodyWidth.value + 40;
let flag = true;
let nums = props.num;
let lgxl = bodyWidth_ >= 1070 && nums <= 4;
let md = bodyWidth_ >= 992 && nums <= 3;
let sm = bodyWidth_ >= 768 && nums <= 3;
if (lgxl || md || sm) flag = false;
return flag;
});
function setBodyWidth() {
try {
bodyWidth.value = (<any>(
document.getElementsByClassName("gl-search-form-norepat")[0]
)).offsetWidth;
} catch (err) {}
}
async function setOpenStatu() {
isOpen.value = !isOpen.value;
isAnim.value = true;
nextTick(() => {
setTableHeight();
});
}
//点击展开收起动态计算表格的高度
async function setTableHeight() {
const dom: Element | null = document.getElementById("serch-card");
if (dom)
await nextTick(() => {
const el: any = dom || "";
const secHeight: number = el.getBoundingClientRect().height;
let height =
document.body.offsetHeight -
(typeof secHeight === "number" ? secHeight : 98.55);
const tableHeight = props.isShowForm ? height - 250 : height - 240;
console.log(tableHeight, "tableHeight");
emit("getTableHeight", tableHeight);
});
}
function addMethods() {
emit("addMethods");
}
return {
isShowMore,
setBodyWidth,
setOpenStatu,
isOpen,
addMethods,
};
},
});
</script>
<style lang="less" scoped>
@import "./index.less";
</style>
引入的样式:(src/components/searchForm/index.less)
@height: 120px;
@white: #FFFFFF;
.gl-serachForm {
background: @white;
width: 100%;
border-radius: 5px;
padding: 10px 20px;
@media only screen and (min-width: 680px) {
.ant-col-xs-12 {
width: 50%;
}
}
@media only screen and (min-width: 766px) {
.ant-col-xs-12 {
width: 50%;
}
}
@media only screen and (min-width: 840px) {
.ant-col-md-8 {
width: 33.33333%;
}
}
@media only screen and (min-width: 100px) {
.ant-col-lg-6 {
width: 25%;
}
}
@media only screen and (min-width: 1320px) {
.ant-col-xxl-6 {
width: 25%;
}
}
.el-col {
white-space: nowrap;
}
.gl-search-top,
.gl-search-top-open {
transition: all 0.25s ease;
height: @height;
overflow: hidden;
border-radius: 4px;
border: none;
padding: 0 10px;
.search-form-title {
font-weight: 700;
font-size: 1rem;
line-height: 28px;
}
.search-button {
display: inline-block;
float: right;
}
.form-an-btn {
display: inline;
}
.search-btn {
width: 215px;
padding-top: 3px;
float: right;
text-align: right;
}
.gl-search-open-close,
.gl-search-open,
.gl-search-close {
cursor: pointer;
text-align: center;
font-size: 12px;
margin-left: 8px;
.icon {
transition: all 0.2s ease-in-out;
transform: rotate(90deg);
}
}
.gl-search-open {
.icon {
transform: rotate(-90deg) !important;
}
}
.gl-search-close {
.icon {
transform: rotate(90deg) !important;
}
}
}
.gl-search-top-open {
height: auto;
}
}
页面组件使用示例
<template>
<div>
<a-form
layout="inline"
ref="formExpertRef"
:colon="false"
:model="formState"
:labelCol="{ span: 8 }"
:wrapperCol="{ span: 16 }"
>
<searchFrom
:num="5"
@searchTable="searchTable(true)"
@resetForm="resetForm"
@getTableHeight="getTableHeight"
>
<template #search-title>
<div style="display: inline-block;">首页</div>
</template>
<template #form_1>
<a-form-item label="aa" name="aa">
<a-input
v-model:value="formState.aa"
placeholder="请输入"
class="formWidth"
allowClear
/>
</a-form-item>
</template>
<template #form_2>
<a-form-item label="bb" name="bb">
<a-input
v-model:value="formState.bb"
placeholder="请输入"
class="formWidth"
allowClear
/>
</a-form-item>
</template>
<template #form_3>
<a-form-item label="cc" name="cc">
<a-input
v-model:value="formState.cc"
placeholder="请输入"
class="formWidth"
allowClear
/>
</a-form-item>
</template>
<template #form_4>
<a-form-item label="dd" name="dd">
<a-input
v-model:value="formState.dd"
placeholder="请输入"
class="formWidth"
allowClear
/>
</a-form-item>
</template>
<template #form_5>
<a-form-item label="ee" name="ee">
<a-input
v-model:value="formState.ee"
placeholder="请输入"
class="formWidth"
allowClear
/>
</a-form-item>
</template>
</searchFrom>
</a-form>
<a-table
bordered
:columns="columns"
:data-source="tableData"
:pagination="false"
:scroll="{ y:tableHeight }"
size="small"
style="width: 98%; margin: 10px auto"
>
<template #bodyCell="{ text, record, index, column }">
<template v-if="column.key === 'operation'">
<a class="btnStyle" @click.stop="detail(text)">详情</a>
</template>
</template>
</a-table>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, reactive } from "vue";
import searchFrom from "@/components/searchForm/index.vue";
const tableHeight=ref<number>()
// 重置表单
const formExpertRef = ref();
const resetForm = () => {
formExpertRef.value.resetFields();
searchTable();
};
//表格是否可滚动高度
function getTableHeight(height:number){
tableHeight.value=height
}
//查询
async function searchTable(isSearchBtn?: Boolean) {
let param = {
...formState,
// page_no: isSearchBtn ? 1 : pages.page,
// page_size: pages.pageSize,
};
}
</script>
还有个问题懒得解决了 搜索条件字段长度不一致时对齐问题 如果有大佬解决了请麻烦评论下方哦