Vue3 ElementPlus el-cascader 组件:开启单选模式后,点击标签文字直接选中,无需点击单选框

在elementPlus中el-cascader开启checkStrictly: true,会出现单选框

在这里插入图片描述
出现单选框之后,无法点击label来触发选中的操作了!!!

需求:需要点击label来选中对应的选项

Vue3 ElementPlus el-cascader 组

解决思路

  1. 获取所有的选项节点
  2. 监听每个节点的click事件
  3. 当某个节点的click事件被触发,就要找到该节点里面的redio或者checkbox,触发该表单元素的点击事件,进而实现,勾选功能。

我们需要使用 @visibleChange事件

const visibleChange = async () => {
  await nextTick() //等待页面渲染完毕
  setCascaderLabelEvent()
}

const setCascaderLabelEvent = () => {
//获取页面中展示的节点
  let casecaderMenuList = document.querySelectorAll(
    '.esg-popupConatiner .el-cascader-node',
  )

  let optLabels = casecaderMenuList

  optLabels.forEach((item) => {
  
    item.removeEventListener('click', (event) => {
      checkOptions(event, item)
    }) // 移除之前的事件监听器
    //监听节点
    item.addEventListener('click', (event) => {
      checkOptions(event, item)
    })
  })
}


const checkOptions = async (event, item) => {
  const input = item.querySelector(
    'input[type="checkbox"], input[type="radio"]',
  ) // 支持复选框和单选框

  if (input) {
    input.click() // 模拟点击复选框
  }
  await nextTick() //等待渲染 完成后重新监听,当然也可以根据需求自行控制是否要关闭悬浮窗
  setCascaderLabelEvent()
}

自定义label插槽时候,数据过多会出现性能问题

例如:级联选择器某个子集数据内容过多,不适用于懒加载,并且节点文字内容很长,撑满了屏幕,需要固定悬浮窗的宽度,隐藏超出内容,并且通过el-popover组件显示完整内容

通过插槽内将节点包裹一个div 监听div的鼠标移入事件 ,并将它对应的value或者唯一键赋值与响应式变量,根据变量判断是否即时单个加载部分dom


  <template>

  <el-cascader
                style="width: 100%" 
                popper-class="esg-popupConatiner"
                ref="cascaderRef"
                @visible-change="visibleChange"
                v-model="categoryName"
                :options="productCategory"
                :props="{
                  checkStrictly: true,
                  label: 'name',
                  value: 'name',
                }"
              >
                <template #default="{ data }">
                  <div
                    class="optionNode"
                    @mouseenter="
                      () => {
                        hoverData = data.name
                      }
                    "
                  >
                    <el-popover
                      trigger="hover"
                      placement="left"
                      v-if="hoverData === data.name"
                      :popper-style="{
                        maxWidth: '400px',
                        width: 'auto',
                      }"
                      :content="data.name"
                    >
                      <template #reference>
                        {{ data.name }}
                      </template>
                    </el-popover>

                    <template v-else>
                      {{ data.name }}
                    </template>
                  </div>
                </template>
              </el-cascader>
</template>
<script setup>
import { ref, nextTick } from 'vue'
const hoverData = ref(null)
const visibleChange = async () => {
  await nextTick()
  setCascaderLabelEvent()
}
const setCascaderLabelEvent = () => {
  let casecaderMenuList = document.querySelectorAll(
    '.esg-popupConatiner .el-cascader-node',
  )

  let optLabels = casecaderMenuList

  optLabels.forEach((item) => {
    item.removeEventListener('click', (event) => {
      checkOptions(event, item)
    }) // 移除之前的事件监听器
    item.addEventListener('click', (event) => {
      checkOptions(event, item)
    })
  })
}

const checkOptions = async (event, item) => {
  const input = item.querySelector(
    'input[type="checkbox"], input[type="radio"]',
  ) // 支持复选框和单选框

  if (input) {
    input.click() // 模拟点击复选框
  }
  await nextTick()

  setCascaderLabelEvent()
}
</script>
<style lang="scss">
.esg-popupConatiner {
  .el-cascader-menu {
    max-width: 300px;
    .optionNode {
      // display: block;
      user-select: none;
      width: 260px;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }
}
</style>

如果是其他的自定义节点的需求,有过多的元素,dom,那么建议采用虚拟dom的方式,用来减轻压力

Vue2 中,`el-cascader` 是 Element UI 提供的一个下拉级联选择组件,用于实现层级数据的选择。如果想要在设置 `filterable` 搜索功能时,遇到重复选项只显示一个,可以采取以下步骤: 1. **初始化组件**: 首先,在组件的配置中开启 `filterable` 属性,并传递一个筛选函数,该函数会在用户输入时过滤数据列表。 ```html <el-cascader :options="options" filterable :remote-filter="remoteFilter" /> ``` 2. **remoteFilter 函数**: 这是一个处理远程搜索的数据过滤函数,你可以在这里对数据进行去重处理。当搜索结果中有重复项时,保留第一个匹配的项。示例如下: ```javascript data() { return { options: [], // 添加一个临时变量存储已经查找过的值 searchedValues: [] }; } methods: { remoteFilter(value) { const result = this.options.filter(item => { if (this.searchedValues.includes(item.value)) { return false; // 如果已存在,则返回false,不显示重复项 } // 其他过滤逻辑... // 使用item.label 或 item.value 对象进行比较,这里简化为value字段 return item.value.includes(value); }); this.searchedValues.push(value); // 将当前搜索的值添加到已搜索集合中 return result; } } ``` 3. **清除重复值**: 可能还需要一个方法来清空 `searchedValues` 当用户关闭搜索框或改变搜索内容,以便下次搜索时从头开始。 ```javascript methods: { clearSearch() { this.searchedValues.length = 0; } } ``` 然后,在需要的地方调用 `clearSearch()`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值