踩坑日记 Vue Cannot read properties of undefined (reading '_wrapper')

前言

最近遇到一个比较紧急的需求,由于时间紧张需要同步大量的代码,因此我开始了频繁的复制粘贴,删除修改代码的工作。

在我处理一个弹窗相关的问题时,我遇到了比较有意思的异常:

js 复制代码
 Cannot read properties of undefined (reading '_wrapper')

问题排查

当时的控制台报错类似如下:

明眼人一下子就注意到了,上面xxx 函数未定义,click 事件拿到一个 undefined

当时的情况比较复杂,控制台的异常远远不止这些,而且高强度的开发让我没注意到上面的提示信息。

于是直接从这个报错下手:

js 复制代码
 Cannot read properties of undefined (reading '_wrapper')

(1)确认异常代码

我们可以看到 _wrapper 是一个没有被定义的变量,于是我先从异常提示中进行排查,点开异常之后我们可以看到下面的代码提示:

显然这并不是我的代码,应该是某些依赖的内容报错了,我首先怀疑的是这个vue的源码。

(2)查看异常代码

打开本地的vue源码,很久没复习的缘故很多细节记不清了,但是大概流程还是知道的。

我们直接在vue源码项目中搜索 _wrapper,我们可以看到代码如下所示:

代码解释

  • add 函数用于向目标元素添加事件监听器。
  • 它接受四个参数: name 表示事件名称, handler 表示事件处理函数, capture 表示是否在捕获阶段触发事件, passive 表示是否以被动方式监听事件。
  • 在函数内部,它首先处理了一个异步边缘情况,即当点击事件触发补丁(patch)时,事件处理程序附加到外部元素并再次触发。
  • 函数保存了事件处理程序附加的时间戳,并且只有当传递给它的事件的时间戳晚于附加时间戳时,事件处理程序才会触发。
  • 最后,函数通过调用 target.addEventListener 方法将事件监听器添加到目标元素上。
  • 如果浏览器支持 passive 选项,则会将 { capture, passive } 作为第三个参数传递给 addEventListener 方法,否则只传递 capture 参数。

(3)错误原因

核心如下:

js 复制代码
const original = handler;
handler = original._wrapper = function (e) {
      if (
        // no bubbling, should always fire.
        // this is just a safety net in case event.timeStamp is unreliable in
        // certain weird environments...
        e.target === e.currentTarget ||
        // event is fired after handler attachment
        e.timeStamp >= attachedTimestamp ||
        // bail for environments that have buggy event.timeStamp implementations
        // #9462 iOS 9 bug: event.timeStamp is 0 after history.pushState
        // #9681 QtWebEngine event.timeStamp is negative value
        e.timeStamp <= 0 ||
        // #9448 bail if event is fired in another document in a multi-page
        // electron/nw.js app, since event.timeStamp will be using a different
        // starting reference
        e.target.ownerDocument !== document
      ) {
        return original.apply(this, arguments)
      }
    }

代码接受了handler 事件处理函数,赋值给 original,然后original._wrapper 赋值给 handler

假如 handler 为undefined,那么 original._wrapper 赋值给 handler 就会出现 _wrapper未定义错误,同时也会提示绑定事件got 一个 undefined的内容,所以问题原因就是存在未注册的函数。

问题处理

排除控制台中提示的未定义函数名称,并移除这个函数名称相关的事件绑定即可。

总结

这个问题很简单,主要还是我不够细心导致的。

但在这个问题中也可以了解到,对于频繁开发的vue或者react项目的同学来说,学习源码还是很重要的,必要时面向源码开发可以解决很多问题。

相关推荐
m0_547486666 分钟前
《JavaScript核心原理 》全套PPT课件2026
开发语言·javascript·ecmascript
xm_xm_xm_143 分钟前
react17版本以前类组件常用操作
前端·javascript·react.js
冬奇Lab2 小时前
一天一个开源项目(第200篇):next-forge - 生产级 Next.js SaaS 启动模板
前端·前端框架·开源
lzhdim2 小时前
13、JavaScript事件循环机制 - JavaScript学习系列文章
开发语言·前端·javascript·学习·ecmascript
liangshanbo12152 小时前
Vue 3 <script setup> 的本质原理是什么?它与普通 setup()有何区别?
前端·javascript·vue.js
七牛开发者4 小时前
实测推荐 3 个 Skill,轻松上手 Codex 网页设计与交付流程
前端·javascript·后端
七牛开发者4 小时前
拆解 dsh 系列:从源码和版本变化看 DeepSeek Harness 的设计取舍
前端·javascript·后端
谭光志5 小时前
如何从网站提取设计风格:DOM、计算样式与 DESIGN.md
前端·javascript·agent
柒和远方5 小时前
V079: Milvus 向量数据库:AI 日记本的三组件部署、集合字段建模与余弦索引
javascript·sql
水獭比特5 小时前
Anthropic Files / Skills 迁移:Workspace 不是租户隔离,API Key 也不是用户身份
javascript