在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
所以,确保不要在事件处理器属性中使用括号调用函数,除非你真的想传递一个函数的返回值给该属性,而不是传递函数本身。在大多数情况下,你都是想传递函数本身以便在事件发生时调用它。
以上是我发现的一个基础但不容易发现的踩坑点,如有错误,请指正