【面试 - el-select问题及解决】wujie 微前端下子系统 el-select 多选 filterable 过滤失效

目录

  • [1. 问题描述](#1. 问题描述)
  • [2. wujie 微前端下 el-select 多选 filterable 过滤失效问题修复](#2. wujie 微前端下 el-select 多选 filterable 过滤失效问题修复)
    • [2.1 问题现象](#2.1 问题现象)
    • [2.2 根因分析](#2.2 根因分析)
      • [2.2.1 问题一:事件对象在防抖延迟期间失效](#2.2.1 问题一:事件对象在防抖延迟期间失效)
      • [2.2.2 问题二:isOnComposition 状态被错误锁定](#2.2.2 问题二:isOnComposition 状态被错误锁定)
    • [2.3 解决方案](#2.3 解决方案)
    • [2.4 修复原理](#2.4 修复原理)
    • [2.5 适用范围](#2.5 适用范围)
    • [2.6 相关文件](#2.6 相关文件)

1. 问题描述

  • 系统A 单独运行的时候 select下拉数据不论多选还是单选,filter 过滤都正常,
  • 但是系统A通过 wujie 的方式嵌到系统B时,
    • 系统A单选的 select 使用 filter 过滤时正常,
    • 多选的 select 使用 filter 过滤时下拉数据没有变(没有触发过滤),
  • 这是为什么?怎么解决

2. wujie 微前端下 el-select 多选 filterable 过滤失效问题修复

2.1 问题现象

环境 单选 + filterable 多选 + filterable
独立运行 正常 正常
wujie 嵌入 正常 失效(输入字母无过滤,输入中文报错)

错误信息:Uncaught TypeError: Cannot read properties of null (reading 'value')

2.2 根因分析

Element UI 的 el-select单选多选 模式下使用了不同的过滤输入处理路径

  • 单选模式debouncedOnInputChange → 内部读取 this.query(组件响应式数据),不依赖事件对象
  • 多选模式debouncedQueryChange → 内部读取 e.target.value(事件对象属性)

debouncedQueryChange 是一个 300ms 防抖函数,在 wujie 沙箱环境中存在两个问题:

2.2.1 问题一:事件对象在防抖延迟期间失效

wujie 会代理/合成事件(isTrusted: false),这些合成事件在 handler 返回后会被回收。300ms 后防抖回调执行时 e.target 已为 null,导致:

  • 输入字母 → 取不到值,过滤不触发
  • 输入中文 → 报错 Cannot read properties of null (reading 'value')

2.2.2 问题二:isOnComposition 状态被错误锁定

wujie 沙箱中多选输入框动态创建时,可能触发 compositionstart 但不触发 compositionend,导致 Element UI 内部 isOnComposition 卡在 truehandleQueryChange 进入后直接 return,过滤逻辑被跳过。

2.3 解决方案

src/main.js 的 wujie 补丁块(if (window.$wujie) { ... })中添加以下代码,完全替换 debouncedQueryChange,不依赖 event 对象,改为直接从 DOM 读值:

js 复制代码
if (window.$wujie) {
  const components = ['ElSelect', 'ElDatePicker', 'ElTimePicker', 'ElCascader', 'ElAutocomplete']
  components.forEach((name) => {
    const comp = Vue.component(name)
    if (!comp) return
    Vue.component(name, {
      extends: comp,
      props: {
        popperAppendToBody: { type: Boolean, default: false },
        appendToBody: { type: Boolean, default: false },
        popperClass: { type: [String, Array], default: 'insert-wujie_popper-class' },
        collapseTags: { type: Boolean, default: true }
      }
    })
  })

  // 修复 wujie 环境下多选 el-select filterable 过滤无效问题
  // 根因:debouncedQueryChange 是防抖函数(延迟300ms执行),内部通过 e.target.value 取值,
  // 但 wujie 沙箱中事件对象在防抖延迟期间会被回收/失效(isTrusted:false 的合成事件尤其严重),
  // 导致延迟回调执行时 e.target 已为 null 或值丢失,过滤逻辑不触发或报错
  // 解决:完全不依赖 event 对象,防抖回调内直接从 DOM 读取输入值
  Vue.mixin({
    beforeMount() {
      if (this.$options.name === 'ElSelect' && this.debouncedQueryChange) {
        const vm = this
        this.debouncedQueryChange = debounce(function() {
          // 重置 isOnComposition,防止 wujie 下 compositionend 未触发导致阻塞
          vm.isOnComposition = false
          // 直接从 DOM 读取多选过滤输入框的当前值,不依赖可能已失效的 event 对象
          const input = vm.$el && vm.$el.querySelector('.el-select__input')
          const val = input ? input.value : vm.query || ''
          vm.handleQueryChange(val)
        }, 300)
      }
    }
  })
}

注意:debounce 来自项目已引入的 lodash.debounce

2.4 修复原理

复制代码
用户输入 → input 事件触发 debouncedQueryChange()
                    ↓
            [等待 300ms 防抖]
                    ↓
        ┌─── 原始方案(失效)────┐     ┌─── 新方案(可靠)─────┐
        │ 读 e.target.value      │     │ 读 DOM input.value     │
        │ (事件已被 wujie 回收)  │     │ (DOM 元素始终存在)     │
        │ → null → 报错/无值     │     │ → 取到正确输入值       │
        └────────────────────────┘     └────────────────────────┘
                                                ↓
                                    vm.isOnComposition = false
                                                ↓
                                    vm.handleQueryChange(val) → 过滤生效 ✓

2.5 适用范围

所有使用 Element UI 2.x + wujie 微前端 的项目,只要出现多选 select 过滤失效的问题,都可以使用此方案修复。

2.6 相关文件

  • 修复位置:src/main.js(wujie 补丁块内)
  • 影响组件:所有使用 el-select + multiple + filterable 的页面
相关推荐
吃口巧乐兹1 小时前
AI 全栈时代,为什么要服务端使用 NestJs
前端
yingyima1 小时前
Redis 延迟任务队列:凌晨3点服务器报警的救星
前端
weiggle2 小时前
第三篇:可组合函数(Composable)——Compose 的基石
android·前端
前端环境观察室2 小时前
别只看 task success:AI Agent 浏览器自动化真正要补的是环境证据链
前端·后端
huakoh2 小时前
LangChain 实战:用混合检索啃下 1000 页 PDF,搭一个长文档问答 Agent
前端
Dazer0072 小时前
Edge 浏览器绕过 HTTPS 证书错误
前端·https·edge
元让_vincent2 小时前
Spark 2.0:面向 Web 的 3DGS 可视化与大场景渲染平台详解
前端·3d·spark·渲染·轻量化·3dgs·lod
KaMeidebaby2 小时前
卡梅德生物技术快报|酵母双杂交 cDNA 文库构建与蛋白互作筛选流程
服务器·前端·数据库·人工智能·算法
沐风___2 小时前
App 上架之后:如何看数据、获取用户与持续迭代产品
服务器·前端·数据库