在Vue中使用jsx踩坑,关于事件监听器的绑定的踩坑点

279 阅读2分钟

在Vue中使用jsx踩坑,关于事件监听器的绑定的踩坑点

本人在做demo的时候,在jsx中写了以下代码

import { defineComponent } from 'vue';  //导入模块
  
export default defineComponent({  //定义组件
  setup() {  
    const containerMousedown = (event) => {  
      // 处理鼠标按下事件  
    };  
  
    return () => (  
        // 在这里鼠标按下时,就调用containerMousedown函数
      <div onMouseDown={containerMousedown()}>  
        {/* 其他内容 */}  
      </div>  
    );  
  },  
});

目的是为了鼠标按下的时候调用containerMousedown函数,但是后面发现功能实现不了,经过很久的调试发现了问题

因为我多了个括号!

正确写法如下:

import { defineComponent } from 'vue';  //导入模块
  
export default defineComponent({  //定义组件
  setup() {  
    const containerMousedown = (event) => {  
      // 处理鼠标按下事件  
    };  
  
    return () => (  
        // 在这里鼠标按下时,就调用containerMousedown函数
        //不加括号!!!
      <div onMouseDown={containerMousedown}>  
        {/* 其他内容 */}  
      </div>  
    );  
  },  
});

那到底为什么加了括号就有问题?

原来是因为在jsx中,我实际上是想把containerMousedown函数作为一个事件处理器传递给onMouseDown属性,当鼠标按下时,vue会自动调用这个函数。

但是如果加了括号,会在组件渲染时立即调用containerMousedown函数,并将函数返回值作为事件监听器,多数情况下返回值是undefined,因此,鼠标按下时不会有任何函数被调用,导致代码无法按预期工作

当然在js中也是一样的,在原生 JavaScript 中绑定事件监听器时,也不应该在添加监听器时调用函数(即不应该加括号)。相反,应该将函数本身作为监听器的回调传递。加括号会导致函数在绑定监听器时立即执行

正确示例代码如下:

const container = document.getElementById('container');   //获取dom元素
  
function containerMousedown(event) {  
  // 处理鼠标按下事件  
}  
  
// 正确绑定事件监听器,不调用函数  //不加括号!!!
container.addEventListener('mousedown', containerMousedown);
v

所以,确保不要在事件处理器属性中使用括号调用函数,除非你真的想传递一个函数的返回值给该属性,而不是传递函数本身。在大多数情况下,你都是想传递函数本身以便在事件发生时调用它。

以上是我发现的一个基础但不容易发现的踩坑点,如有错误,请指正