vue2添加标签组件可滚动

文章讲述了在Vue项目中,如何使用el组件实现一个可滚动的标签管理功能,包括输入框、下拉选择框、按钮的布局和滚动逻辑,以及标签增加、删除时的响应和滚动调整。

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

这里用el的组件来实现,一般标签组件又要带输入效果,所以是需要el-tag和el-input组件进行组合

截图中红色为组件封装的区域,蓝色是输入框所在的区域

左边是下拉选择框已封装好的组件,右边则是一个按钮,修改了样式,并且是绝对定位,所以是中间容器宽度需要考虑的因素之一

新增实现效果

1. 需要标签和输入框所在区域可滚动,可以查看到所有的标签

2. 需要选择标签和输入标签时时,可以完整地看到新增的标签

3. 需要取消勾选和打叉掉不要的标签时,可以出现回滚的效果

实现效果如下

当标签增加就左移,减少就右移

实现

下面代码实际是vue2+vue3组合式api的项目

1. 定义所有要用到且会影响实现效果的数据

const scrollContainer = ref() //滚动容器元素
const hasScrolled = ref(false) //是否可以滚动
const tagsRef = ref() //目前存在的标签
const deleteTagWidth = ref() // 删除标签的宽度
const inputWidth = 270 // 输入框设置的宽度
const buttonWidth = 36 // 按钮遮挡的宽度
const isInputFocusHiddenTag = ref(false) //点击空白区域会聚焦输入框,此时标签被遮挡的参数

2. 检测滚动容器是否可以滚动

    const checkScroll = () => {
      context.root.$nextTick(() => {
        hasScrolled.value = isError.value
          ? scrollContainer.value.scrollWidth > (scrollContainer.value.clientWidth - buttonWidth)
          : (scrollContainer.value.scrollWidth - inputWidth) > (scrollContainer.value.clientWidth - buttonWidth)
      })
    }

这边有对于标签数量做显示,如果标签数量超过时会报错,并且输入框会隐藏,所以对于是否出错做了一下处理,没有出错就是(容器滚动宽度 > 容器宽度 - 右侧按钮宽度),出错则还需要去除一下输入框的宽度

3. 标签增加时调用函数

    const leftScroll = () => {
      context.root.$nextTick(() => {
        if (hasScrolled.value) {
          // 根据要求,当focus遮挡前面的标签时,再添加标签时,需要滚动到最前面
          if (isInputFocusHiddenTag.value) initPlaceScroll()
          else {
            const offset = tagsRef.value[tagsRef.value.length - 1].$el.offsetWidth
            scrollContainer.value.scrollTo({
              left: scrollContainer.value.scrollLeft + offset,
              top: 0,
              behavior: 'smooth'
            })
          }
        }
      })
    }

拿到标签列表最后一个标签的宽度,之后左移+该宽度

4. 标签删除时调用函数

 const rightScroll = () => {
      context.root.$nextTick(() => {
        if (hasScrolled.value) {
          scrollContainer.value.scrollTo({
            left: scrollContainer.value.scrollLeft - deleteTagWidth.value,
            top: 0,
            behavior: 'smooth'
          })
        } else {
          initPlaceScroll()
        }
      })
    }

删除标签列表的那个标签的宽度会被记录到deleteTagWidth上,去除掉就可以了

5. 无法滚动则重置到正常的滚动状态

 const initPlaceScroll = () => {
      scrollContainer.value.scrollTo({
        top: 0,
        left: 0,
        behavior: 'smooth'
      })
      isInputFocusHiddenTag.value = false
    }

6. 监视标签增加和减少的列表

watch(() => checkedList.value.length, (nv, ov) => {
      checkScroll()
      if (nv > ov) {
        leftScroll()
      } else {
        rightScroll()
      }
    })

7. 隐藏容器滚动条,改成滚轮横向滚动

需要添加@wheel事件到滚动容器上

  const handleWheel = (e) => {
      const offset = e.deltaY
      scrollContainer.value.scrollTo(scrollContainer.value.scrollLeft + offset, 0)
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值