react【portals】与vue3【<Teleport>】

它们都是为了解决同一个问题:将组件的子节点渲染到存在于父组件 DOM 层次结构之外的 DOM 节点中。

核心概念对比

特性 React Vue 3
功能 将子节点渲染到父组件 DOM 结构之外 将其包裹的内容移动到应用 DOM 结构中的指定位置
API ReactDOM.createPortal(children, domNode) <Teleport> 组件 + to 属性
代码位置 通常在 render() 方法或组件返回值中使用 作为模板中的标签使用

举例:

公共 HTML 结构 (index.html)

html 复制代码
<body>
  <div id="root"></div> <!-- React 应用挂载点 -->
  <div id="app"></div> <!-- Vue 应用挂载点 -->
  <!-- 模态框将要被渲染到这个节点 -->
  <div id="modal-root"></div>
</body>

1. React 实现:使用 Portals

jsx 复制代码
// Modal.jsx
import React, { PureComponent } from 'react'
import { createPortal } from "react-dom"

export class Modal extends PureComponent {
  render() {
    return createPortal(this.props.children,   document.getElementById('modal-root') ))
  }
}
jsx 复制代码
// App.jsx
import React, { PureComponent } from 'react'
import { createPortal } from "react-dom"
import Modal from './Modal'

export class App extends PureComponent {
  render() {
    return (
      <div className='app'>
        <h1>App H1</h1>
        {
          createPortal(<h2>App H2</h2>, document.querySelector("#why"))
        }

        {/* 2.Modal组件 */}
        <Modal>
          <h2>我是标题</h2>
          <p>我是内容, 哈哈哈</p>
        </Modal>
      </div>
    )
  }
}

export default App

2. Vue 3 实现:使用 <Teleport>

vue 复制代码
<!-- Modal.vue -->
<template>
  <Teleport to="#modal-root" v-if="isOpen">
    <div class="modal-overlay" @click="$emit('close')">
      <div class="modal-content" @click.stop>
        <button @click="$emit('close')">关闭</button>
        <slot></slot>
      </div>
    </div>
  </Teleport>
</template>

<script setup>
defineProps(['isOpen']);
defineEmits(['close']);
</script>
vue 复制代码
<!-- App.vue -->
<template>
  <div class="app">
    <h1>我的 Vue 应用</h1>
    <button @click="isModalOpen = true">打开模态框</button>
    <!-- 即使 Modal 在这里被使用,它的 HTML 将被 Teleport 到 #modal-root -->
    <Modal :is-open="isModalOpen" @close="isModalOpen = false">
      <p>这是从 Vue Teleport 渲染的内容!</p>
    </Modal>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import Modal from './components/Modal.vue';

const isModalOpen = ref(false);
</script>

关键区别与共同点

共同点:

  1. 逻辑位置不变 :在 React 的虚拟 DOM 树或 Vue 的组件树中,Modal 组件仍然位于 App 组件的子节点位置。这意味着它仍然能继承父组件的上下文(React Context / Vue Provide/Inject),事件冒泡在虚拟树中也会正常发生。
  2. DOM 位置改变 :最终生成的 HTML 结构被移动到了指定的目标容器(如 #modal-root)中。

区别:

方面 React Portal Vue 3 <Teleport>
语法 是一个函数 ReactDOM.createPortal() 是一个内置组件 <Teleport>
条件渲染 通常在 Portal 外部使用 if (!isOpen) return null; 可以在 <Teleport> 标签上使用 v-ifv-show
目标指定 通过函数第二个参数(DOM 节点)指定 通过 to 属性(CSS 选择器字符串)指定
组合性 更偏向函数式,可在逻辑中动态创建 更偏向声明式,作为模板的一部分

总结

React Portals 等于 Vue 3 的 <Teleport> 组件。

它们都是用于"传送"DOM结构的解决方案。虽然语法和实现方式不同(React 是函数调用,Vue 是组件声明),但它们解决了完全相同的问题,并且设计理念也高度一致。如果你熟悉其中一个,理解另一个将毫无障碍。

相关推荐
用户47949283569154 小时前
React 19.2 重磅更新:终于解决 useEffect 依赖数组难题
前端·react.js
梦里小白龙4 小时前
前端视频课程添加水印,全屏不消失解决方法
前端·音视频
我命由我123454 小时前
PDFBox - PDDocument 与 byte 数组、PDF 加密
java·服务器·前端·后端·学习·java-ee·pdf
@PHARAOH4 小时前
HOW - prefetch 二级页面实践
前端·javascript·react.js
EF@蛐蛐堂4 小时前
WUJIE VS QIANKUN 微前端框架选型(一)
前端·vue.js·微服务·架构
前端OnTheRun4 小时前
React18学习笔记(六) React中的类组件,极简的状态管理工具zustand,React中的Typescript
react.js·组件·
咚咚咚小柒4 小时前
【前端】用el-popover做通用悬停气泡(可设置弹框宽度)
前端·javascript·vue.js·elementui·html·scss
Ares-Wang4 小时前
CSS3》》 transform、transition、translate、animation 区别
前端·css·css3
fsnine5 小时前
Python Web框架对比与模型部署
开发语言·前端·python