

vue 搜索框搜索条件自适应布局,搜索框的内容太多了放不下的解决方法。vue3 搜索条件 如果太多了一行显示不下怎么办。按钮自适应布局

Vue3 搜索条件自适应布局方案
在 Vue3 中处理搜索条件在不同屏幕尺寸下的显示问题,可以使用以下几种方法实现自适应布局:
1. 使用 CSS Flexbox 的自动换行
<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 的自动布局
<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>
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 示例
<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 方案)
<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; /* 跨两列 */
}
}
条件+有两个按钮的布局组合实例(按钮一前一后,扩大两倍后的布局)
让宽度占用两列,因为按钮基本只有输入框的一半,所以减少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; /* 跨三列 */
// }
}
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)