事件处理
OpenInula 提供了简单直观的事件处理机制,使用 onXxx
属性来绑定事件处理函数。
基本用法
点击事件
最常用的事件处理是点击事件:
function ClickCounter() {
let count = 0;
function handleClick() {
count++;
}
return (
<button onClick={handleClick}>
点击次数:{count}
</button>
);
}
内联事件处理
对于简单的事件处理,可以直接使用内联函数:
function SimpleButton() {
let message = '';
return (
<div>
<button onClick={() => message = '你好!'}>
打招呼
</button>
<p>{message}</p>
</div>
);
}
常用事件
表单事件
处理表单输入和提交:
function LoginForm() {
let username = '';
let password = '';
function handleSubmit(e) {
e.preventDefault();
console.log('提交登录:', { username, password });
}
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={username}
onInput={e => username = e.target.value}
placeholder="用户名"
/>
<input
type="password"
value={password}
onInput={e => password = e.target.value}
placeholder="密码"
/>
<button type="submit">登录</button>
</form>
);
}
鼠标事件
处理鼠标相关事件:
function MouseTracker() {
let position = { x: 0, y: 0 };
return (
<div
onMouseMove={e => {
position = {
x: e.clientX,
y: e.clientY
};
}}
style={{ height: '200px', background: '#f0f0f0' }}
>
<p>鼠标位置:{position.x}, {position.y}</p>
</div>
);
}
键盘事件
处理键盘输入:
function KeyboardInput() {
let pressedKeys = [];
return (
<input
onKeyDown={e => {
pressedKeys = [...pressedKeys, e.key];
}}
onKeyUp={e => {
pressedKeys = pressedKeys.filter(key => key !== e.key);
}}
placeholder="请按键..."
/>
);
}
事件修饰符
OpenInula 支持事件修饰符来简化常见的事件处理场景:
function EventModifiers() {
return (
<div>
{/* 阻止默认行为 */}
<a onClick={e => e.preventDefault()} href="#">
阻止默认跳转
</a>
{/* 停止事件传播 */}
<div onClick={() => console.log('外层点击')}>
<button
onClick={e => {
e.stopPropagation();
console.log('按钮点击');
}}
>
点击我
</button>
</div>
</div>
);
}
自定义事件
在组件间通信时,可以通过 props 传递自定义事件处理函数:
function CustomButton({ onClick, children }) {
return (
<button
onClick={e => {
// 可以在这里添加自定义逻辑
console.log('按钮被点击');
onClick?.(e);
}}
>
{children}
</button>
);
}
function App() {
return (
<CustomButton onClick={() => console.log('处理点击')}>
点击我
</CustomButton>
);
}
最佳实践
1. 事件处理函数命名
建议使用 handle
前缀命名事件处理函数:
function UserForm() {
let formData = {
name: '',
email: ''
};
function handleNameChange(e) {
formData.name = e.target.value;
}
function handleEmailChange(e) {
formData.email = e.target.value;
}
function handleSubmit(e) {
e.preventDefault();
console.log('提交表单:', formData);
}
return (
<form onSubmit={handleSubmit}>
<input
value={formData.name}
onChange={handleNameChange}
/>
<input
value={formData.email}
onChange={handleEmailChange}
/>
<button type="submit">提交</button>
</form>
);
}
2. 事件参数处理
在需要传递额外参数时,使用箭头函数包装:
function ItemList() {
const items = ['项目1', '项目2', '项目3'];
function handleItemClick(item, index, e) {
console.log('点击项目:', item, '索引:', index, '事件:', e);
}
return (
<ul>
<for each={items}>
{(item, index) => (
<li onClick={(e) => handleItemClick(item, index, e)}>
{item}
</li>
)}
</for>
</ul>
);
}
3. 性能优化
对于频繁触发的事件,考虑使用节流或防抖:
function SearchInput() {
let searchTerm = '';
let timeoutId;
function handleInput(e) {
// 使用防抖处理搜索
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
searchTerm = e.target.value;
console.log('搜索:', searchTerm);
}, 300);
}
willUnmount(() => {
clearTimeout(timeoutId);
});
return (
<input
type="text"
onInput={handleInput}
placeholder="搜索..."
/>
);
}
注意事项
- 事件处理函数中的
this
绑定 - 避免在渲染函数中创建内联函数
- 记得清理定时器和事件监听器
- 注意事件冒泡和捕获的顺序
下一步
学习完事件处理后,你可以: