85 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Vue
		
	
	
			
		
		
	
	
			85 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Vue
		
	
	
| <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>
 |