事件处理 #

一、事件基础 #

1.1 事件绑定 #

Solid 使用类似 React 的事件绑定方式,事件名使用驼峰命名。

jsx
function Button() {
  const handleClick = () => {
    console.log('Button clicked');
  };

  return (
    <button onClick={handleClick}>
      Click me
    </button>
  );
}

1.2 事件对象 #

jsx
function Form() {
  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Form submitted');
  };

  const handleInput = (e) => {
    console.log('Input value:', e.target.value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input onInput={handleInput} />
      <button type="submit">Submit</button>
    </form>
  );
}

二、常见事件类型 #

2.1 鼠标事件 #

jsx
function MouseEvents() {
  return (
    <div
      onClick={() => console.log('click')}
      onDoubleClick={() => console.log('double click')}
      onMouseEnter={() => console.log('mouse enter')}
      onMouseLeave={() => console.log('mouse leave')}
      onMouseDown={() => console.log('mouse down')}
      onMouseUp={() => console.log('mouse up')}
    >
      Mouse Events Demo
    </div>
  );
}

2.2 键盘事件 #

jsx
function KeyboardEvents() {
  const handleKeyDown = (e) => {
    console.log('Key:', e.key);
    console.log('Code:', e.code);
    console.log('Ctrl:', e.ctrlKey);
    console.log('Shift:', e.shiftKey);
  };

  return (
    <input
      onKeyDown={handleKeyDown}
      onKeyUp={(e) => console.log('Key up:', e.key)}
    />
  );
}

2.3 表单事件 #

jsx
function FormEvents() {
  const [value, setValue] = createSignal('');

  return (
    <form onSubmit={(e) => e.preventDefault()}>
      <input
        value={value()}
        onInput={(e) => setValue(e.target.value)}
        onChange={(e) => console.log('Change:', e.target.value)}
        onFocus={() => console.log('Focused')}
        onBlur={() => console.log('Blurred')}
      />
      <select onChange={(e) => console.log('Selected:', e.target.value)}>
        <option value="1">Option 1</option>
        <option value="2">Option 2</option>
      </select>
    </form>
  );
}

三、事件处理模式 #

3.1 内联处理 #

jsx
<button onClick={() => setCount(c => c + 1)}>
  Increment
</button>

3.2 函数引用 #

jsx
function Counter() {
  const [count, setCount] = createSignal(0);

  const increment = () => setCount(c => c + 1);
  const decrement = () => setCount(c => c - 1);

  return (
    <div>
      <button onClick={decrement}>-</button>
      <span>{count()}</span>
      <button onClick={increment}>+</button>
    </div>
  );
}

3.3 传递参数 #

jsx
function TodoList() {
  const [todos, setTodos] = createSignal([
    { id: 1, text: 'Learn Solid' },
    { id: 2, text: 'Build app' }
  ]);

  const deleteTodo = (id) => {
    setTodos(prev => prev.filter(t => t.id !== id));
  };

  return (
    <ul>
      <For each={todos()}>
        {(todo) => (
          <li>
            {todo.text}
            <button onClick={() => deleteTodo(todo.id)}>
              Delete
            </button>
          </li>
        )}
      </For>
    </ul>
  );
}

四、事件委托 #

4.1 使用事件委托 #

jsx
function ButtonGroup() {
  const handleClick = (e) => {
    const action = e.target.dataset.action;
    switch (action) {
      case 'save':
        console.log('Save');
        break;
      case 'cancel':
        console.log('Cancel');
        break;
    }
  };

  return (
    <div onClick={handleClick}>
      <button data-action="save">Save</button>
      <button data-action="cancel">Cancel</button>
    </div>
  );
}

五、自定义事件 #

5.1 回调 Props #

jsx
function CustomButton(props) {
  return (
    <button onClick={props.onAction}>
      {props.label}
    </button>
  );
}

// 使用
<CustomButton
  label="Click me"
  onAction={() => console.log('Action!')}
/>

5.2 事件发射器模式 #

jsx
function EventEmitter(props) {
  const emit = (eventName, data) => {
    const handler = props[`on${eventName}`];
    if (handler) handler(data);
  };

  return (
    <button onClick={() => emit('Click', { timestamp: Date.now() })}>
      Emit Event
    </button>
  );
}

六、最佳实践 #

6.1 命名规范 #

jsx
// 好的命名
<button onClick={handleClick}>Click</button>
<form onSubmit={handleSubmit}>...</form>
<input onChange={handleChange} />

// 避免
<button onClick={click}>Click</button>

6.2 阻止默认行为 #

jsx
// 表单提交
<form onSubmit={(e) => {
  e.preventDefault();
  handleSubmit();
}}>

// 链接点击
<a href="#" onClick={(e) => {
  e.preventDefault();
  navigate('/path');
}}>
  Link
</a>

6.3 事件处理函数组织 #

jsx
function MyComponent() {
  // 状态
  const [count, setCount] = createSignal(0);

  // 事件处理函数
  const handlers = {
    increment: () => setCount(c => c + 1),
    decrement: () => setCount(c => c - 1),
    reset: () => setCount(0)
  };

  return (
    <div>
      <button onClick={handlers.decrement}>-</button>
      <span>{count()}</span>
      <button onClick={handlers.increment}>+</button>
      <button onClick={handlers.reset}>Reset</button>
    </div>
  );
}

七、总结 #

7.1 常用事件 #

类型 事件
鼠标 onClick, onDoubleClick, onMouseEnter, onMouseLeave
键盘 onKeyDown, onKeyUp, onKeyPress
表单 onSubmit, onChange, onInput, onFocus, onBlur
拖拽 onDrag, onDrop, onDragOver

7.2 最佳实践 #

  1. 使用驼峰命名事件处理函数
  2. 合理使用事件委托
  3. 及时阻止默认行为
  4. 组织好事件处理函数
最后更新:2026-03-28