zy-vue-library/components/search/index.vue

85 lines
3.1 KiB
Vue
Raw Permalink Normal View History

2025-10-22 11:19:51 +08:00
<template>
<el-form :model="modelValue" :label-width="labelWidth" @submit.prevent="emits('submit')">
<el-row :class="className">
<template v-if="options && options.length">
<form-items-renderer v-model="modelValue" :options="options" :span="6" :collapse="collapse" :auto-generate-required="false">
<template v-for="(_, name) in slots" :key="name" #[name]="slotProps">
<slot :name="name" v-bind="slotProps" />
</template>
</form-items-renderer>
</template>
<template v-else>
<slot :collapse="collapse"></slot>
</template>
<el-col :span="showCollapseButton ? (collapse ? 6 : span) : span">
<el-form-item label-width="10px" class="end">
<el-button type="primary" native-type="submit"> 搜索 </el-button>
<el-button native-type="reset" @click="emits('submit')">
重置
</el-button>
<template v-if="showCollapseButton">
<el-button v-if="collapse" :icon="ArrowDown" link text type="primary" @click="changeSearchCollapse">
展开
</el-button>
<el-button v-if="!collapse" :icon="ArrowUp" link text type="primary" @click="changeSearchCollapse">
收起
</el-button>
</template>
</el-form-item>
</el-col>
<el-col v-if="slots.button" :span="24">
<el-form-item label-width="0">
<slot name="button"></slot>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script setup>
import { nextTick, onMounted, ref, useSlots, watch } from "vue";
import { uniqueId } from "lodash-es";
import { ArrowDown, ArrowUp } from "@element-plus/icons-vue";
import { ElForm, ElRow, ElCol, ElFormItem, ElButton } from "element-plus";
import "element-plus/es/components/form/style/css";
import "element-plus/es/components/row/style/css";
import "element-plus/es/components/col/style/css";
import "element-plus/es/components/form-item/style/css";
import "element-plus/es/components/button/style/css";
import FormItemsRenderer from "../form_builder/form_items_renderer.vue";
const slots = useSlots();
defineOptions({
name: "AppSearch",
});
const props = defineProps({
labelWidth: { type: String, default: "110px" },
options: { type: Array, default: () => [] },
});
const modelValue = defineModel({ type: Object, required: true });
const emits = defineEmits(["submit"]);
const className = ref(uniqueId("_"));
const span = ref(6);
const showCollapseButton = ref(false);
const collapse = ref(true);
const changeSearchCollapse = () => {
collapse.value = !collapse.value;
};
onMounted(() => {
watch(
() => props.options,
async () => {
await nextTick();
const colEl = document.querySelectorAll(`.${className.value} .el-col`);
const colElLength = colEl.length;
const excludeLast = colElLength - (slots.button ? 2 : 1);
span.value = { 0: 24, 1: 18, 2: 12, 3: 6 }[excludeLast % 4];
showCollapseButton.value = excludeLast > 3;
},
{ immediate: true }
);
});
</script>
<style scoped lang="scss"></style>