vue 搜索框搜索条件自适应布局,搜索框的内容太多了放不下的解决方法。vue3 搜索条件 如果太多了一行显示不下怎么办。按钮自适应布局 电脑版发表于:2025/5/12 11:22 [TOC] ## Vue3 搜索条件自适应布局方案 在 Vue3 中处理搜索条件在不同屏幕尺寸下的显示问题,可以使用以下几种方法实现自适应布局: ### 1. 使用 CSS Flexbox 的自动换行 ```html <template> <div class="search-container"> <div v-for="item in searchItems" :key="item.id" class="search-item"> <!-- 每个搜索条件的内容 --> <input v-model="item.value" :placeholder="item.label" /> </div> </div> </template> <style scoped> .search-container { display: flex; flex-wrap: wrap; gap: 10px; /* 设置元素之间的间距 */ } .search-item { flex: 1 1 auto; /* 允许元素伸缩 */ min-width: 200px; /* 设置最小宽度,防止过小 */ } /* 可选:在大屏幕上设置固定数量 */ @media (min-width: 1200px) { .search-container { display: grid; grid-template-columns: repeat(5, 1fr); /* 大屏显示5列 */ } } /* 中等屏幕 */ @media (min-width: 768px) and (max-width: 1199px) { .search-container { display: grid; grid-template-columns: repeat(3, 1fr); /* 中屏显示3列 */ } } /* 小屏幕 */ @media (max-width: 767px) { .search-container { display: grid; grid-template-columns: 1fr; /* 小屏显示1列 */ } } </style> ``` ### 2. 使用 CSS Grid 的自动布局 ```html <template> <div class="search-grid"> <div v-for="item in searchItems" :key="item.id" class="search-item"> <!-- 搜索条件内容 --> </div> </div> </template> <style scoped> .search-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; } /* 响应式调整 */ @media (max-width: 768px) { .search-grid { grid-template-columns: 1fr; } } </style> ``` tn2> grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); 的解释 **minmax() 函数** 我们有时候想给网格元素一个最小和最大的尺寸,minmax() 函数产生一个长度范围,表示长度就在这个范围之中都可以应用到网格项目中。它接受两个参数,分别为最小值和最大值。grid-template-columns: 1fr 1fr minmax(300px, 2fr) 的意思是,第三个列宽最少也是要 300px,但是最大不能大于第一第二列宽的两倍。 **auto-fill 关键字** 表示自动填充,让一行(或者一列)中尽可能的容纳更多的单元格。grid-template-columns: repeat(auto-fill, 200px) 表示列宽是 200 px,但列的数量是不固定的,只要浏览器能够容纳得下,就可以放置元素 ### 3. 使用第三方组件库 如果你使用的是 Element Plus、Ant Design Vue 等组件库,它们通常内置了响应式布局: #### Element Plus 示例 ```html <template> <el-row :gutter="20"> <el-col v-for="item in searchItems" :key="item.id" :xs="24" :sm="12" :md="8" :lg="6" :xl="4"> <el-form-item :label="item.label"> <el-input v-model="item.value" /> </el-form-item> </el-col> </el-row> </template> ``` ### 4. 动态计算每行显示数量(JavaScript 方案) ```html <template> <div class="search-container"> <template v-for="(row, rowIndex) in rows" :key="rowIndex"> <div class="search-row"> <div v-for="item in row" :key="item.id" class="search-item"> <!-- 搜索条件内容 --> </div> </div> </template> </div> </template> <script setup> import { ref, computed, onMounted } from 'vue'; const searchItems = ref([...]); // 你的搜索条件数组 const screenWidth = ref(window.innerWidth); const calculateRows = () => { const itemsPerRow = Math.floor(screenWidth.value / 250); // 250是每个元素的估计宽度 const rows = []; for (let i = 0; i < searchItems.value.length; i += itemsPerRow) { rows.push(searchItems.value.slice(i, i + itemsPerRow)); } return rows; }; const rows = computed(() => calculateRows()); const handleResize = () => { screenWidth.value = window.innerWidth; }; onMounted(() => { window.addEventListener('resize', handleResize); }); </script> <style scoped> .search-container { width: 100%; } .search-row { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 10px; } .search-item { flex: 1 1 200px; min-width: 200px; } </style> ``` ## 使用grid布局的方案中如果某一个条件的宽度有点特殊,需要进行特殊设置的解决方法 ### 方法1:设置某个条件占更多的列,比如2列 比如给需要更多宽度的条件加上一个样式special-item,然后设置占用两列 ``` .special-item { // min-width: 300px; grid-column: span 2; /* 设置占用两列 */ } ``` 需要设置一下多占用的列,不然只给这个特殊条件单独设置一个宽度是不行的,因为当某个网格项需要特殊宽度时,如果是设置宽度会影响整体的布局和自动换行行为的,如果如果使用这种占用更多列的方式来解决,就要调整一下最小宽度以及特殊条件的宽度,让它刚好是n倍宽度这种,用户体验会更好。 #### 实例: ``` <!-- 搜索区域 --> <el-card class="mb20"> <div class="search-grid"> <el-input v-model="searchForm.userNickname" placeholder="请输入用水户" clearable /> <el-select v-model="state.choiseTown" @change="changeTown" placeholder="请选择乡镇" class="searchinput" size="default"> <el-option v-for="sh in state.townList" :key="sh.townId" :value="sh.townId" :label="sh.name" /> </el-select> <el-select v-model="state.choiseVillage" placeholder="请选择村" class="searchinput" size="default" clearable> <el-option v-for="sh in state.villageList" :key="sh.villageId" :value="sh.villageId" :label="sh.name" /> </el-select> <div class="special-item"> <el-date-picker v-model="searchForm.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" clearable /> </div> <div> <el-button type="primary" @click="handleSearch">搜索</el-button> <!-- <el-button @click="resetSearch">重置</el-button> --> </div> </div> </el-card> <style lang="scss" scoped> .search-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 2fr)); gap: 10px; // 特殊宽度 .special-item { // width: 360px; grid-column: span 2; /* 设置占用两列 */ } // .searchinput { // width: 199px; // } } </style> ``` ### 方法2:直接把每列的宽度设置好 因为搜索条件一般还是固定的个数,而不是非常动态的,所以这样设置也可以。一边需要设置动态,一边又需要自适应,这种方法貌似有点矛盾。 ## 实例 ### 条件+有两个按钮的布局组合实例(两个按钮在后面)  ``` <!-- 搜索区域 --> <el-card class="mb15"> <div class="search-grid"> <el-input size="default" v-model="state.tableData.param.key" clearable placeholder="请输入用户名称"> </el-input> <el-select v-model="state.townId" filterable @change="changeTown" placeholder="请选择乡镇" class="search-item searchinput" size="default" clearable > <el-option v-for="sh in state.townList" :key="sh.townId" :value="sh.townId" :label="sh.name" /> </el-select> <el-select v-model="state.villageId" filterable @change="changeVillage" placeholder="请选择村" class="search-item searchinput" size="default" clearable > <el-option v-for="sh in state.villageList" :key="sh.villageId" :value="sh.villageId" :label="sh.name" clearable /> </el-select> <el-select v-model="state.groupId" filterable placeholder="请选择小组" @change="handleSearch" class="search-item searchinput" size="default" clearable > <el-option v-for="sh in state.groupList" :key="sh.groupId" :value="sh.groupId" :label="sh.groupName" /> </el-select> <div style="display: flex"> <el-button size="default" @click="getTableData" type="primary"> <el-icon> <ele-Search /> </el-icon> 查询 </el-button> <el-button size="default" type="success" @click="onOpenAddUser('add')"> <el-icon> <ele-FolderAdd /> </el-icon> 导入 </el-button> </div> </div> </el-card> ``` **样式:** ``` .search-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 2fr)); gap: 10px; // 特殊宽度 .special-item { grid-column: span 2; /* 跨两列 */ } } ``` ### 条件+有两个按钮的布局组合实例(按钮一前一后,扩大两倍后的布局)  tn2> 让宽度占用两列,因为按钮基本只有输入框的一半,所以减少minmax中的宽度为原来的一半,然后设置占两份,这样相当于扩大一倍,然后按钮只占用一份,这样就可以实现按钮基本只有输入框的一半的效果了。按钮宽度是85,所以最小宽度可以设置为85,但是要注意长度不同的情况下实际1份分的宽度可能不一样。 **view:** ``` <!-- 搜索区域 --> <el-card class="mb15"> <div class="search-grid"> <div> <el-button type="primary" :icon="Plus" size="default" @click="openAddPool">添加 </el-button> </div> <el-select v-model="state.townId" filterable @change="changeTown" placeholder="请选择乡镇" class="search-item searchinput" size="default" clearable > <el-option v-for="sh in state.townList" :key="sh.townId" :value="sh.townId" :label="sh.name" /> </el-select> <el-select v-model="state.villageId" filterable @change="changeVillage" placeholder="请选择村" class="search-item searchinput" size="default" clearable > <el-option v-for="sh in state.villageList" :key="sh.villageId" :value="sh.villageId" :label="sh.name" clearable /> </el-select> <el-select v-model="state.groupId" filterable placeholder="请选择小组" @change="handleSearch" class="search-item searchinput" size="default" clearable > <el-option v-for="sh in state.groupList" :key="sh.groupId" :value="sh.groupId" :label="sh.groupName" /> </el-select> <el-input v-model="pageParam.key" placeholder="名称" class="searchinput" size="default" clearable /> <div> <el-button type="primary" :icon="Search" size="default" @click="getPoolList">搜索</el-button> </div> </div> </el-card> ``` **样式** ``` // 按钮宽度是85,所以最小宽度可以设置为85,但是要注意长度不同的情况下实际1份分的宽度可能不一样 .search-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(85px, 2fr)); gap: 10px; /* 让宽度占用两列,因为按钮基本只有输入框的一半,所以减少minmax中的宽度为原来的一半,然后设置占两份, 这样相当于扩大一倍,然后按钮只占用一份,这样就可以实现按钮基本只有输入框的一半的效果了 */ .searchinput { grid-column: span 2; } } ``` ### 条件+有三个按钮的布局组合实例(按钮一前一后,每列的宽度缩小一倍) **页面布局:** ``` <!-- 搜索区域 --> <el-card class="mb15"> <div class="search-grid"> <el-input size="default" class="search-item" v-model="state.tableData.param.key" clearable placeholder="请输入用户名称"> </el-input> <el-select v-model="state.townId" filterable @change="changeTown" placeholder="请选择乡镇" class="search-item searchinput" size="default" clearable > <el-option v-for="sh in state.townList" :key="sh.townId" :value="sh.townId" :label="sh.name" /> </el-select> <el-select v-model="state.villageId" filterable @change="changeVillage" placeholder="请选择村" class="search-item searchinput" size="default" clearable > <el-option v-for="sh in state.villageList" :key="sh.villageId" :value="sh.villageId" :label="sh.name" clearable /> </el-select> <el-select v-model="state.groupId" filterable placeholder="请选择小组" @change="handleSearch" class="search-item searchinput" size="default" clearable > <el-option v-for="sh in state.groupList" :key="sh.groupId" :value="sh.groupId" :label="sh.groupName" /> </el-select> <div style="display: flex" class="search-item"> <el-button size="default" @click="getTableData" type="primary"> <el-icon> <ele-Search /> </el-icon> 查询 </el-button> <!-- 把四个文字的按钮放在里边的,这样和两个文字的按钮刚好占用2列 --> <el-button size="default" type="success" @click="openTemplateDialogVisible"> <el-icon> <ele-Download /> </el-icon> 模板下载 </el-button> <input type="file" ref="fileInut" style="display: none" @change="handleFileUpload" /> </div> <!-- 两个文字的按钮单独放一行, --> <el-button size="default" type="success" @click="openChoiseFile"> <el-icon> <ele-FolderAdd /> </el-icon> 导入 </el-button> </div> </el-card> ``` **样式:** ``` // 每列的宽度缩小一倍 .search-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(86px, 2fr)); gap: 10px; .search-item { grid-column: span 2; /* 跨两列 */ } // 特殊宽度 // .special-item { // grid-column: span 3; /* 跨三列 */ // } } ```