vue H5页面实现搜索历史记录超过两行的Tag的展开与折叠

该博客介绍了一个在搜索页面中实现搜索历史记录折叠和展开的场景。当搜索历史超过两行时,通过计算每个标签的offsetLeft来判断行数,并据此隐藏多余的标签。代码包括HTML、CSS和JavaScript部分,展示了如何动态添加‘展开’和‘收起’按钮,以及处理点击事件来切换显示状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近项目中遇到一个场景,搜索页面搜索历史记录超过两行要折叠,同时可以展开显示所有的历史记录。
实现方法:判断每个标签的offsetLeft,每行的offsetLeft相同,依据这个判断当前有多少行。

代码

html代码
      <div class="search-new-history-content">
        <div class="search-new-history-content-top" :class="[textToggle ? '' : 'active']" ref="historyRef">
          <span v-for="(item,index) in historyTag" :key="index" ref="tagRef" @click="clickTag(item)"
                :class="[item.title === '展开' || item.title === '收起'? 'chu' : '']">
            {{ item.title }}
            <img v-if="item.title === '展开'" src="/static/bytx/subject/more_down.svg" alt="">
            <img v-if="item.title === '收起'" src="/static/bytx/subject/more_up.svg" alt="">
          </span>
        </div>
      </div>
css
    &-content{
      position: relative;
      padding-left: 20px;
      padding-right: 20px;
      &-top{
         margin-top: 16px;
        span{
          display: inline-block;
          padding: 8px 12px 10px 8px;
          border-radius: 6px;
          margin-right: 12px;
          word-break: keep-all;
          background: #F5F6F7;
          font-size: 14px;
          font-family: PingFangSC-Regular, PingFang SC;
          font-weight: 400;
          color: #282828;
          line-height: 20px;
        }
        .chu{
          display: inline-block;
          font-size: 13px;
          font-family: PingFangSC-Regular, PingFang SC;
          font-weight: 400;
          color: #9D9D9D;
          background: transparent;
          padding: 0;
          vertical-align: middle;
          img{
            transform: translateY(2px);
          }
        }
      }
      .active{
        height: auto;
        overflow: visible;
      }
    }
js
    this.historyTag = [{id: 0, title: '血液病'},{id: 7, title: '血液病有哪几种'},
            {id: 3, title: '儿童淋巴瘤'}, {id: 4, title: '喉咙痛声音嘶哑'}, {id: 5, title: '咽喉癌的早期症状'},
            {id: 6, title: '成人淋巴癌'},{id: 1, title: '肺癌'},{id: 2, title: '白血病'}
          ]
  // 首先调用默认收起的方法        
 this.defaultClose()
 // 历史搜索默认收起
    defaultClose() {
      this.$nextTick(() => {
        if (!this.historyTag || !this.historyTag.length) {
          return
        }
        let offsetLeft = 0;
        this.line = 0
        let tags = this.$refs.tagRef
        tags.forEach((item,index) => {
          if (index === 0) {
            this.line = 1
            offsetLeft = item.offsetLeft
          } else if (item.offsetLeft === offsetLeft) {
          // 如果某个标签的offsetLeft和第一个标签的offsetLeft相等  说明增加了一行
            this.line++
          }
          if (this.line > 1) {
          // 从第2行开始  设置marginTop
            item.style.marginTop = 12 + 'px'
          }
          if (this.line > 2) {
          	//从第3行开始 隐藏标签 
            item.style.display = 'none'
            // 显示展开按钮  class名chu是在前面动态添加的
            if (item.className === 'chu') {
              item.style.display = 'inline-block'
              item.style.marginTop = 0 + 'px'
            }
          }
        })
        if (this.line > 2) {
        	// 超过2行  手动添加“展开”按钮
          this.historyTag.push({id:0, title: '展开'})
        }
        let index = this.historyTag.findIndex((item) => {
          return item.title === '收起'
        })
        // 折叠状态  删除“收起”按钮
        if (index > -1) {
          this.historyTag.splice(index, 1)
        }

      })

    },
    // 历史搜索展开
    openAll() {
      let tags = this.$refs.tagRef
      let index = this.historyTag.findIndex((item) => {
        return item.title === '展开'
      })
      // 展开状态  删除“展开”按钮
      this.historyTag.splice(index, 1, )
      // 添加“收起”按钮
      this.historyTag.splice(tags.length - 1, 0, {id:0, title: '收起'})
      // 将所有的标签都显示
      tags.forEach((item,index) => {
        item.style.display = 'inline-block'
      })
    }

    // 点击某个历史搜索
    clickTag(item) {
      if (item.title === '展开') {
        this.openAll()
      } else if (item.title === '收起') {
        this.defaultClose()
      } else {
       	
      }

    }

实现效果

在这里插入图片描述
在这里插入图片描述

<think>我们正在寻找支持多选功能的国内UI组件库。根据引用内容,我们可以关注基于Vue的UI组件库,因为引用中提到了View UI(原iView)以及一些国内优秀的Vue UI库。同时,引用[3]提到了Android的UI组件,但用户的问题更倾向于前端UI组件(因为提到了Vue),所以我们主要关注Vue生态。 国内支持多选功能的UI组件库(主要针对Vue): 1. **View UI (原iView)**:这是一个高质量的基于Vue的UI组件库,主要用于中后台系统。它提供了丰富的组件,其中就包括支持多选的下拉菜单(Select组件)、多选框(Checkbox)等。它的多选功能非常完善,支持搜索、全选、分组等。[^1] 2. **Element UI**:由饿了么前端团队开源,在国内使用非常广泛。它提供了Select多选、Checkbox多选等组件,支持多选、搜索、自定义模板等功能。 3. **Ant Design Vue**:这是Ant Design的Vue实现,同样是一个企业级UI设计语言和React实现,而Vue版本由社区维护。它提供了Select多选、TreeSelect(树形选择)等多选组件,支持多选、搜索、标签展示等。 4. **Vant**:有赞团队开源的移动端Vue组件库,提供了多选组件,如Checkbox多选框组、Select等,适合移动端场景。 5. **TDesign**:腾讯开源的UI组件库,支持Vue2/Vue3/React等多个框架,提供了多选框组、多选选择器等组件。 以上这些组件库都支持多选功能,并且在国内有大量的使用案例和文档支持。 关于多选功能的实现,这些组件库通常提供以下特性: - 多选下拉菜单(支持搜索、远程搜索、分组等) - 多选框组(Checkbox Group) - 树形多选(TreeSelect) - 标签展示已选项 - 全选/反选 用户可以根据自己的技术栈(Vue2/Vue3)以及项目类型(PC端/移动端)选择合适的组件库。 如果用户使用的是小程序,那么可以考虑使用微信小程序的原生组件(如checkbox-group)或者使用小程序UI组件库,例如: - Vant Weapp:有赞团队的小程序UI组件库,提供了多选组件。 - iView Weapp:View UI的小程序版本。 因此,总结如下: - PC端Vue项目:View UI, Element UI, Ant Design Vue, TDesign - 移动端Vue项目:Vant - 小程序:Vant Weapp, iView Weapp 注意:引用[1]中提到的View UI(iView)是一个专注于PC端的组件库,而引用[2]中提到了国内Vue UI组件库在国际上的认可,说明这些组件库的质量很高。 如果用户需要具体的多选组件示例,可以查看对应组件库的官方文档。 相关问题: 1. 如何在小程序中使用Vant Weapp的多选组件? 2. Element UI的多选下拉菜单如何实现远程搜索? 3. Ant Design Vue的TreeSelect组件如何实现多选? 4. View UI(iView)的多选组件如何限制选择数量? 5. 移动端多选组件有哪些设计上的注意事项?</think>基于您的需求,以下是国内支持多选功能的优秀UI组件库推荐: ### 1. View UI(原iView)[^1] - **多选组件**:`Select` 组件支持多选模式(`multiple`属性) - **特点**: ```html <Select v-model="value" multiple> <Option v-for="item in list" :value="item.value" :key="item.value">{{ item.label }}</Option> </Select> ``` - 支持搜索过滤、远程搜索 - 提供标签式展示已选项 - 支持分组选择(OptionGroup) - **适用场景**:PC端中后台系统 ### 2. Element Plus(饿了么团队) - **多选组件**:`el-select` + `multiple`属性 - **亮点功能**: ```html <el-select v-model="value" multiple filterable collapse-tags> <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"/> </el-select> ``` - 支持折叠标签(`collapse-tags`) - 虚拟滚动支持大数据量(>10,000条) - 完整的键盘导航支持 ### 3. Ant Design Vue(蚂蚁金服) - **多选组件**:`a-select` + `mode="multiple"` - **特色功能**: ```html <a-select v-model:value="value" mode="multiple" :maxTagCount="2"> <a-select-option v-for="item in data" :key="item.value">{{item.label}}</a-select-option> </a-select> ``` - 标签数量控制(`maxTagCount`) - 支持自定义选项渲染 - Ant Design设计体系深度集成 ### 4. Vant(有赞团队 - 移动端首选) - **多选组件**:`CheckboxGroup` - **移动端优化**: ```html <van-checkbox-group v-model="checked" max="5"> <van-checkbox v-for="item in list" :key="item" :name="item"/> </van-checkbox-group> ``` - 手势操作友好 - 支持最大选择数量限制(`max`) - 提供瀑布流式选择器(Cascader) ### 5. TDesign(腾讯开源) - **多选方案**: - 树形多选(`tree-select`) - 表格多选(`table` + 选择列) - 标签选择器(`tag-input`) - **优势**: - 支持Vue2/Vue3/React多框架 - 提供企业级复杂选择场景解决方案 - 完整的无障碍访问支持 ### 选择建议: 1. **PC端管理后台** → View UI / Element Plus 2. **移动端H5** → Vant 3. **大型企业应用** → Ant Design Vue / TDesign 4. **需要复杂树形选择** → TDesign树形选择器 所有组件库均提供完善的文档和示例,支持通过`multiple`属性或专用组件实现多选功能,并包含搜索过滤、标签展示、选择限制等增强功能。[^1][^2]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值