Portal传送门 #

一、Portal 概述 #

1.1 什么是 Portal #

Portal 允许将子元素渲染到 DOM 树中的不同位置,而不是父组件内部。

jsx
import { Portal } from 'solid-js/web';

function Modal() {
  return (
    <Portal>
      <div class="modal">Modal Content</div>
    </Portal>
  );
}

1.2 Portal 用途 #

用途 说明
模态框 避免 z-index 和 overflow 问题
下拉菜单 防止被父容器裁剪
工具提示 确保正确显示位置
通知消息 全局显示位置

二、基本用法 #

2.1 渲染到 body #

jsx
import { Portal } from 'solid-js/web';

function App() {
  const [show, setShow] = createSignal(false);

  return (
    <div>
      <button onClick={() => setShow(true)}>Open Modal</button>
      <Show when={show()}>
        <Portal>
          <div class="modal-overlay" onClick={() => setShow(false)}>
            <div class="modal-content">
              <h2>Modal Title</h2>
              <button onClick={() => setShow(false)}>Close</button>
            </div>
          </div>
        </Portal>
      </Show>
    </div>
  );
}

2.2 指定挂载点 #

jsx
<Portal mount={document.getElementById('modal-root')}>
  <div class="modal">Modal Content</div>
</Portal>

三、实际应用 #

3.1 模态框组件 #

jsx
function Modal(props) {
  return (
    <Portal>
      <div class="modal-overlay" onClick={props.onClose}>
        <div class="modal-content" onClick={(e) => e.stopPropagation()}>
          <div class="modal-header">
            <h2>{props.title}</h2>
            <button onClick={props.onClose}>×</button>
          </div>
          <div class="modal-body">{props.children}</div>
        </div>
      </div>
    </Portal>
  );
}

3.2 下拉菜单 #

jsx
function Dropdown(props) {
  const [isOpen, setIsOpen] = createSignal(false);
  let buttonRef;

  return (
    <>
      <button ref={buttonRef} onClick={() => setIsOpen(!isOpen())}>
        {props.label}
      </button>
      <Show when={isOpen()}>
        <Portal>
          <div class="dropdown">
            <For each={props.items}>
              {(item) => <div onClick={item.onClick}>{item.label}</div>}
            </For>
          </div>
        </Portal>
      </Show>
    </>
  );
}

四、最佳实践 #

  1. 确保 Portal 内容有正确的 z-index
  2. 处理键盘事件(如 ESC 关闭)
  3. 点击外部关闭模态框
  4. 阻止事件冒泡

五、总结 #

5.1 Portal API #

属性 说明
mount 指定挂载点
ref 获取 Portal 引用
children Portal 内容

5.2 使用场景 #

  • 模态框和对话框
  • 全局通知
  • 下拉菜单
  • 工具提示
最后更新:2026-03-28