应无所住,而生其心
排名
1
文章
869
粉丝
112
评论
163
net core webapi post传递参数
庸人 : 确实坑哈,我也是下班好了好几次,发现后台传递对象是可以的,但...
百度编辑器自定义模板
庸人 : 我建议换个编辑器,因为现在百度富文本已经停止维护了,用tinymec...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

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

202人阅读 2025/5/12 11:22 总访问:5404518 评论:0 收藏:0 手机
分类: 前端

Vue3 搜索条件自适应布局方案

在 Vue3 中处理搜索条件在不同屏幕尺寸下的显示问题,可以使用以下几种方法实现自适应布局:

1. 使用 CSS Flexbox 的自动换行

  1. <template>
  2. <div class="search-container">
  3. <div v-for="item in searchItems" :key="item.id" class="search-item">
  4. <!-- 每个搜索条件的内容 -->
  5. <input v-model="item.value" :placeholder="item.label" />
  6. </div>
  7. </div>
  8. </template>
  9. <style scoped>
  10. .search-container {
  11. display: flex;
  12. flex-wrap: wrap;
  13. gap: 10px; /* 设置元素之间的间距 */
  14. }
  15. .search-item {
  16. flex: 1 1 auto; /* 允许元素伸缩 */
  17. min-width: 200px; /* 设置最小宽度,防止过小 */
  18. }
  19. /* 可选:在大屏幕上设置固定数量 */
  20. @media (min-width: 1200px) {
  21. .search-container {
  22. display: grid;
  23. grid-template-columns: repeat(5, 1fr); /* 大屏显示5列 */
  24. }
  25. }
  26. /* 中等屏幕 */
  27. @media (min-width: 768px) and (max-width: 1199px) {
  28. .search-container {
  29. display: grid;
  30. grid-template-columns: repeat(3, 1fr); /* 中屏显示3列 */
  31. }
  32. }
  33. /* 小屏幕 */
  34. @media (max-width: 767px) {
  35. .search-container {
  36. display: grid;
  37. grid-template-columns: 1fr; /* 小屏显示1列 */
  38. }
  39. }
  40. </style>

2. 使用 CSS Grid 的自动布局

  1. <template>
  2. <div class="search-grid">
  3. <div v-for="item in searchItems" :key="item.id" class="search-item">
  4. <!-- 搜索条件内容 -->
  5. </div>
  6. </div>
  7. </template>
  8. <style scoped>
  9. .search-grid {
  10. display: grid;
  11. grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  12. gap: 10px;
  13. }
  14. /* 响应式调整 */
  15. @media (max-width: 768px) {
  16. .search-grid {
  17. grid-template-columns: 1fr;
  18. }
  19. }
  20. </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 示例

  1. <template>
  2. <el-row :gutter="20">
  3. <el-col v-for="item in searchItems" :key="item.id"
  4. :xs="24" :sm="12" :md="8" :lg="6" :xl="4">
  5. <el-form-item :label="item.label">
  6. <el-input v-model="item.value" />
  7. </el-form-item>
  8. </el-col>
  9. </el-row>
  10. </template>

4. 动态计算每行显示数量(JavaScript 方案)

  1. <template>
  2. <div class="search-container">
  3. <template v-for="(row, rowIndex) in rows" :key="rowIndex">
  4. <div class="search-row">
  5. <div v-for="item in row" :key="item.id" class="search-item">
  6. <!-- 搜索条件内容 -->
  7. </div>
  8. </div>
  9. </template>
  10. </div>
  11. </template>
  12. <script setup>
  13. import { ref, computed, onMounted } from 'vue';
  14. const searchItems = ref([...]); // 你的搜索条件数组
  15. const screenWidth = ref(window.innerWidth);
  16. const calculateRows = () => {
  17. const itemsPerRow = Math.floor(screenWidth.value / 250); // 250是每个元素的估计宽度
  18. const rows = [];
  19. for (let i = 0; i < searchItems.value.length; i += itemsPerRow) {
  20. rows.push(searchItems.value.slice(i, i + itemsPerRow));
  21. }
  22. return rows;
  23. };
  24. const rows = computed(() => calculateRows());
  25. const handleResize = () => {
  26. screenWidth.value = window.innerWidth;
  27. };
  28. onMounted(() => {
  29. window.addEventListener('resize', handleResize);
  30. });
  31. </script>
  32. <style scoped>
  33. .search-container {
  34. width: 100%;
  35. }
  36. .search-row {
  37. display: flex;
  38. flex-wrap: wrap;
  39. gap: 10px;
  40. margin-bottom: 10px;
  41. }
  42. .search-item {
  43. flex: 1 1 200px;
  44. min-width: 200px;
  45. }
  46. </style>

使用grid布局的方案中如果某一个条件的宽度有点特殊,需要进行特殊设置的解决方法

方法1:设置某个条件占更多的列,比如2列

比如给需要更多宽度的条件加上一个样式special-item,然后设置占用两列

  1. .special-item {
  2. // min-width: 300px;
  3. grid-column: span 2; /* 设置占用两列 */
  4. }

需要设置一下多占用的列,不然只给这个特殊条件单独设置一个宽度是不行的,因为当某个网格项需要特殊宽度时,如果是设置宽度会影响整体的布局和自动换行行为的,如果如果使用这种占用更多列的方式来解决,就要调整一下最小宽度以及特殊条件的宽度,让它刚好是n倍宽度这种,用户体验会更好。

实例:

  1. <!-- 搜索区域 -->
  2. <el-card class="mb20">
  3. <div class="search-grid">
  4. <el-input v-model="searchForm.userNickname" placeholder="请输入用水户" clearable />
  5. <el-select v-model="state.choiseTown" @change="changeTown" placeholder="请选择乡镇" class="searchinput" size="default">
  6. <el-option v-for="sh in state.townList" :key="sh.townId" :value="sh.townId" :label="sh.name" />
  7. </el-select>
  8. <el-select v-model="state.choiseVillage" placeholder="请选择村" class="searchinput" size="default" clearable>
  9. <el-option v-for="sh in state.villageList" :key="sh.villageId" :value="sh.villageId" :label="sh.name" />
  10. </el-select>
  11. <div class="special-item">
  12. <el-date-picker
  13. v-model="searchForm.dateRange"
  14. type="daterange"
  15. range-separator="至"
  16. start-placeholder="开始日期"
  17. end-placeholder="结束日期"
  18. value-format="YYYY-MM-DD"
  19. clearable
  20. />
  21. </div>
  22. <div>
  23. <el-button type="primary" @click="handleSearch">搜索</el-button>
  24. <!-- <el-button @click="resetSearch">重置</el-button> -->
  25. </div>
  26. </div>
  27. </el-card>
  28. <style lang="scss" scoped>
  29. .search-grid {
  30. display: grid;
  31. grid-template-columns: repeat(auto-fill, minmax(160px, 2fr));
  32. gap: 10px;
  33. // 特殊宽度
  34. .special-item {
  35. // width: 360px;
  36. grid-column: span 2; /* 设置占用两列 */
  37. }
  38. // .searchinput {
  39. // width: 199px;
  40. // }
  41. }
  42. </style>

方法2:直接把每列的宽度设置好

因为搜索条件一般还是固定的个数,而不是非常动态的,所以这样设置也可以。一边需要设置动态,一边又需要自适应,这种方法貌似有点矛盾。

实例

条件+有两个按钮的布局组合实例(两个按钮在后面)

  1. <!-- 搜索区域 -->
  2. <el-card class="mb15">
  3. <div class="search-grid">
  4. <el-input size="default" v-model="state.tableData.param.key" clearable placeholder="请输入用户名称"> </el-input>
  5. <el-select
  6. v-model="state.townId"
  7. filterable
  8. @change="changeTown"
  9. placeholder="请选择乡镇"
  10. class="search-item searchinput"
  11. size="default"
  12. clearable
  13. >
  14. <el-option v-for="sh in state.townList" :key="sh.townId" :value="sh.townId" :label="sh.name" />
  15. </el-select>
  16. <el-select
  17. v-model="state.villageId"
  18. filterable
  19. @change="changeVillage"
  20. placeholder="请选择村"
  21. class="search-item searchinput"
  22. size="default"
  23. clearable
  24. >
  25. <el-option v-for="sh in state.villageList" :key="sh.villageId" :value="sh.villageId" :label="sh.name" clearable />
  26. </el-select>
  27. <el-select
  28. v-model="state.groupId"
  29. filterable
  30. placeholder="请选择小组"
  31. @change="handleSearch"
  32. class="search-item searchinput"
  33. size="default"
  34. clearable
  35. >
  36. <el-option v-for="sh in state.groupList" :key="sh.groupId" :value="sh.groupId" :label="sh.groupName" />
  37. </el-select>
  38. <div style="display: flex">
  39. <el-button size="default" @click="getTableData" type="primary">
  40. <el-icon>
  41. <ele-Search />
  42. </el-icon>
  43. 查询
  44. </el-button>
  45. <el-button size="default" type="success" @click="onOpenAddUser('add')">
  46. <el-icon>
  47. <ele-FolderAdd />
  48. </el-icon>
  49. 导入
  50. </el-button>
  51. </div>
  52. </div>
  53. </el-card>

样式:

  1. .search-grid {
  2. display: grid;
  3. grid-template-columns: repeat(auto-fill, minmax(160px, 2fr));
  4. gap: 10px;
  5. // 特殊宽度
  6. .special-item {
  7. grid-column: span 2; /* 跨两列 */
  8. }
  9. }

条件+有两个按钮的布局组合实例(按钮一前一后,扩大两倍后的布局)


让宽度占用两列,因为按钮基本只有输入框的一半,所以减少minmax中的宽度为原来的一半,然后设置占两份,这样相当于扩大一倍,然后按钮只占用一份,这样就可以实现按钮基本只有输入框的一半的效果了。按钮宽度是85,所以最小宽度可以设置为85,但是要注意长度不同的情况下实际1份分的宽度可能不一样。

view:

  1. <!-- 搜索区域 -->
  2. <el-card class="mb15">
  3. <div class="search-grid">
  4. <div>
  5. <el-button type="primary" :icon="Plus" size="default" @click="openAddPool">添加 </el-button>
  6. </div>
  7. <el-select
  8. v-model="state.townId"
  9. filterable
  10. @change="changeTown"
  11. placeholder="请选择乡镇"
  12. class="search-item searchinput"
  13. size="default"
  14. clearable
  15. >
  16. <el-option v-for="sh in state.townList" :key="sh.townId" :value="sh.townId" :label="sh.name" />
  17. </el-select>
  18. <el-select
  19. v-model="state.villageId"
  20. filterable
  21. @change="changeVillage"
  22. placeholder="请选择村"
  23. class="search-item searchinput"
  24. size="default"
  25. clearable
  26. >
  27. <el-option v-for="sh in state.villageList" :key="sh.villageId" :value="sh.villageId" :label="sh.name" clearable />
  28. </el-select>
  29. <el-select
  30. v-model="state.groupId"
  31. filterable
  32. placeholder="请选择小组"
  33. @change="handleSearch"
  34. class="search-item searchinput"
  35. size="default"
  36. clearable
  37. >
  38. <el-option v-for="sh in state.groupList" :key="sh.groupId" :value="sh.groupId" :label="sh.groupName" />
  39. </el-select>
  40. <el-input v-model="pageParam.key" placeholder="名称" class="searchinput" size="default" clearable />
  41. <div>
  42. <el-button type="primary" :icon="Search" size="default" @click="getPoolList">搜索</el-button>
  43. </div>
  44. </div>
  45. </el-card>

样式

  1. // 按钮宽度是85,所以最小宽度可以设置为85,但是要注意长度不同的情况下实际1份分的宽度可能不一样
  2. .search-grid {
  3. display: grid;
  4. grid-template-columns: repeat(auto-fill, minmax(85px, 2fr));
  5. gap: 10px;
  6. /*
  7. 让宽度占用两列,因为按钮基本只有输入框的一半,所以减少minmax中的宽度为原来的一半,然后设置占两份,
  8. 这样相当于扩大一倍,然后按钮只占用一份,这样就可以实现按钮基本只有输入框的一半的效果了
  9. */
  10. .searchinput {
  11. grid-column: span 2;
  12. }
  13. }

条件+有三个按钮的布局组合实例(按钮一前一后,每列的宽度缩小一倍)

页面布局:

  1. <!-- 搜索区域 -->
  2. <el-card class="mb15">
  3. <div class="search-grid">
  4. <el-input size="default" class="search-item" v-model="state.tableData.param.key" clearable placeholder="请输入用户名称"> </el-input>
  5. <el-select
  6. v-model="state.townId"
  7. filterable
  8. @change="changeTown"
  9. placeholder="请选择乡镇"
  10. class="search-item searchinput"
  11. size="default"
  12. clearable
  13. >
  14. <el-option v-for="sh in state.townList" :key="sh.townId" :value="sh.townId" :label="sh.name" />
  15. </el-select>
  16. <el-select
  17. v-model="state.villageId"
  18. filterable
  19. @change="changeVillage"
  20. placeholder="请选择村"
  21. class="search-item searchinput"
  22. size="default"
  23. clearable
  24. >
  25. <el-option v-for="sh in state.villageList" :key="sh.villageId" :value="sh.villageId" :label="sh.name" clearable />
  26. </el-select>
  27. <el-select
  28. v-model="state.groupId"
  29. filterable
  30. placeholder="请选择小组"
  31. @change="handleSearch"
  32. class="search-item searchinput"
  33. size="default"
  34. clearable
  35. >
  36. <el-option v-for="sh in state.groupList" :key="sh.groupId" :value="sh.groupId" :label="sh.groupName" />
  37. </el-select>
  38. <div style="display: flex" class="search-item">
  39. <el-button size="default" @click="getTableData" type="primary">
  40. <el-icon>
  41. <ele-Search />
  42. </el-icon>
  43. 查询
  44. </el-button>
  45. <!-- 把四个文字的按钮放在里边的,这样和两个文字的按钮刚好占用2列 -->
  46. <el-button size="default" type="success" @click="openTemplateDialogVisible">
  47. <el-icon>
  48. <ele-Download />
  49. </el-icon>
  50. 模板下载
  51. </el-button>
  52. <input type="file" ref="fileInut" style="display: none" @change="handleFileUpload" />
  53. </div>
  54. <!-- 两个文字的按钮单独放一行, -->
  55. <el-button size="default" type="success" @click="openChoiseFile">
  56. <el-icon>
  57. <ele-FolderAdd />
  58. </el-icon>
  59. 导入
  60. </el-button>
  61. </div>
  62. </el-card>

样式:

  1. // 每列的宽度缩小一倍
  2. .search-grid {
  3. display: grid;
  4. grid-template-columns: repeat(auto-fill, minmax(86px, 2fr));
  5. gap: 10px;
  6. .search-item {
  7. grid-column: span 2; /* 跨两列 */
  8. }
  9. // 特殊宽度
  10. // .special-item {
  11. // grid-column: span 3; /* 跨三列 */
  12. // }
  13. }

欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价

vue.js+Layer实现表格数据绑定与更新

一:使用Vue.js绑定好数据与更新事件 使用v-on绑定好事件,在事件里边直接把该行数据传递进去,在更新方法里边就可以直接...

vue.js 实现省市联动

HTML代码&lt;divid=&quot;pro_citys&quot;&gt; 省:&lt;selectid=&quot;provice&quot;v-on:change=&quot;prochange()&quo...

vue.js常见问题

一:花括号当做字符串显示的问题1:检查下绑定到vue.js的id是否重复,如果id重复了,就有可能存在这种问题,因为有可能把数...

vue.js常用指令

v-html可以把字符串当成一个html来渲染,而不是原样输出Html类似.net mvc中的@Html.Raw()方法&lt;divv-html=&quot;item.tit...

干货!div滚动到一定位置就固定他vue中实现一侧滚动到底部就固定

尊重原创:转载请注名出处div滚动到一定位置就固定他,例如左边的内容很多,右边的内容很少,如果不处理滚动到一定位置后右...

vue.js常用指令事件绑定等vue过滤器解析状态过滤器多个参数vue表格状态解析vue解析类型element ui解析类型状态el-tag

按照html的编码显示:v-html&lt;div class=&quot;font_info&quot; v-html=&quot;item.Content&quot;&gt;{{item.Content}}&l...

vue.js if用法

vue.js if可以做一些判断例如我们要把下面这个输出varvm=newVue({ el:&quot;#content&quot;, data:{ titles:[&quot;小明...

vue.js 学习日记第一章-安装vue开发环境

官网:https://cn.vuejs.org/v2/guide/ 这是一篇学习性文章,不定时更新,用来记录我学习vue.js的过程。 首先,是v...

vue.js 学习日记第二章-在vue中编写function及一些简单指令

官网:https://cn.vuejs.org/v2/guide/ vue.js 学习日记第一章:http://www.tnblog.net/18323015640/article/details/2...

vue.js 学习日记第三章-vue中的简单事件及事件修饰符

官网:https://cn.vuejs.org/v2/guide/ vue.js 学习日记第二章:http://www.tnblog.net/18323015640/article/details/2...

vue.js 学习日记第四章-vue中文本框数据获取与绑定及computed计算属性

官网:https://cn.vuejs.org/v2/guide/ vue.js学习日记第三章: http://www.tnblog.net/18323015640/article/details/2...

vue.js 学习日记第五章-v-if和v-for指令的使用方式

官网:https://cn.vuejs.org/v2/guide/ vue.js学习日记第四章: http://www.tnblog.net/18323015640/article/details/2...

vue.js 学习日记第六章-vue组件初步学习

官网:https://cn.vuejs.org/v2/guide/ vue.js学习日记第五章: http://www.tnblog.net/18323015640/article/details/2...

vue.js学习日记第七章-搭建脚手架

官网:https://cn.vuejs.org/v2/guide/ vue.js学习日记第六章: http://www.tnblog.net/18323015640/article/details/2...

vue实现好友选中效果

逛过vue官网肯定会发现一个有趣的指令“v-for”,相比与以前拼接html代码确实要上档次一点,而且减少了工作量,先看一波效...

js时间格式化vue.js时间格式化带T 时间格式化

也可以借助moment库, 参考:https://www.tnblog.net/aojiancc2/article/details/8079moment库有点大,推荐可以使用day.js...