V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shintendo
V2EX  ›  Vue.js

请教一个 Vue 的问题,组件销毁后内部的 v-on 没有解除?

  •  
  •   shintendo · 2019-03-29 15:28:22 +08:00 · 2771 次点击
    这是一个创建于 2099 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近碰到一个奇怪的问题,请大手子看一下

    repro: https://codepen.io/niaodan2b/pen/drxQBw

    步骤:把光标放在 input 里,然后关闭 dialog,然后点击页面空白处,会在控制台看到报错

    按我的理解,dialog 关闭的时候,组件就销毁了,此时应该会自动解除内部元素的 v-on:blur 吧?为什么点击页面空白处还会触发呢?

    6 条回复    2019-03-29 23:23:44 +08:00
    keepeye
        1
    keepeye  
       2019-03-29 15:50:13 +08:00
    Note: Document.activeElement 的值随浏览器的不同而不同 (bug 452307): IE10 把值设为焦点将要移向的对象 , 而 Firefox 和 Chrome 往往把值设为 body .

    https://developer.mozilla.org/zh-CN/docs/Web/Events/blur
    shintendo
        2
    shintendo  
    OP
       2019-03-29 16:01:29 +08:00
    @keepeye
    没懂,是说关闭 dialog 后焦点移到了 body 吗?我的意思是关闭 dialog 之后这个 blur 事件为什么依旧存在呢?
    dixeran
        3
    dixeran  
       2019-03-29 16:33:06 +08:00
    chrome 72 有报错,FF 67 没有..
    keepeye
        4
    keepeye  
       2019-03-29 18:08:46 +08:00
    @shintendo
    我猜
    js 怎么知道你 blur 了呢?是不是依靠你点击了 input 的之外的地方?是不是相当于 $("body").onclick 呢?你移除了 input 但是点击事件还在 body 上。
    noe132
        5
    noe132  
       2019-03-29 20:01:06 +08:00
    不是 Vue 也不是 dialog 的问题。
    理论上 input 销毁后只会触发一次 blur。
    chrome 的表现是 blur 后强行 focus,结果元素不存在继续触发 blur,又强行 focus
    因为 vue 是异步渲染的,所以只会有一次报错。我手写了段同步渲染的代码,会导致 chrome 爆栈。
    目测是 chrome 在销毁 input 时的 bug

    https://paste.ubuntu.com/p/G5nys4wWgR/

    打开一个空页面运行这个 run 函数
    点击获取焦点再点外面失去焦点
    同步删除 chrome 会爆栈,异步删除 chrome 会出现你的例子一样的错误

    firefox 和 edge 表现正常

    目测应该给 chromium 提 issue
    建议不要再 blur 里写 focus,或者先判断一下
    shintendo
        6
    shintendo  
    OP
       2019-03-29 23:23:44 +08:00
    @noe132
    原来如此,感谢分析。blur 里写 focus 是因为要接收扫码枪输入,input 是隐藏的,不能让用户点出去
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3045 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 00:35 · PVG 08:35 · LAX 16:35 · JFK 19:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.