当前位置: 首页 > news >正文

插槽vue/react

​作用域插槽(Scoped Slots)​​ 是 Vue 提供的一种​​让插槽内容可以访问子组件内部数据​​的机制,它极大地增强了组件的​​灵活性与复用性​​,是 Vue 组件设计中非常强大的功能之一。


一、vue插槽

先回顾:普通插槽(默认插槽、具名插槽)

在 Vue 中,插槽(slot)是​​父组件向子组件传递一段模板内容(HTML / 组件)的机制​​,用于实现​​内容分发​​。比如:

<!-- 子组件 Child.vue -->
<template><div><slot></slot>  <!-- 普通插槽 --></div>
</template><!-- 父组件 -->
<Child><p>这是插入到子组件中的内容</p>  <!-- 父组件传的内容 -->
</Child>

✅ 这是​​普通插槽​​,父组件传什么,子组件就在 <slot>的位置显示什么。


那什么是​​作用域插槽​​呢?

​作用域插槽(Scoped Slot)​​ 是一种特殊的插槽,它允许​​父组件在插入内容时,可以访问子组件内部的数据​​。

作用域插槽的核心作用,就是让子组件可以把内部的数据“暴露”给父组件,让父组件可以基于这些数据,自由地决定如何渲染插槽内容。​

换句话说:

  • 通常插槽是​​父 → 子 传内容​​;

  • 但作用域插槽是​​子 → 父 传数据,让父组件决定如何渲染这些数据​​。


🔧  作用域插槽的语法(Vue 2 & Vue 3)


✅ Vue 2 中的作用域插槽语法

在子组件中,给 <slot>绑定数据:

<!-- 子组件 Child.vue -->
<template><div><slot :user="user" :items="items"></slot><!-- 把 user 和 items 数据暴露给父组件插槽内容 --></div>
</template><script>
export default {data() {return {user: { name: 'Alice', age: 25 },items: ['Apple', 'Banana', 'Cherry']};}
};
</script>

在父组件中,通过 ​​v-slot(或 slot-scope)​​ 接收子组件传递的数据:

<!-- 父组件 -->
<template><Child><!-- Vue 2 写法1:slot-scope(旧版) --><template slot-scope="{ user, items }"><p>用户名:{{ user.name }}</p><ul><li v-for="item in items" :key="item">{{ item }}</li></ul></template></Child>
</template>

或者 Vue 2 也支持新版语法(推荐,和 Vue 3 类似):

<Child><template #default="{ user, items }"><p>{{ user.name }}</p><ul><li v-for="item in items" :key="item">{{ item }}</li></ul></template>
</Child>

✅ Vue 3 中的作用域插槽语法(更统一、更简洁)

在子组件中,同样通过 <slot :data="xxx">传递数据:

<!-- 子组件 Child.vue -->
<template><div><slot :user="user" :items="items"></slot></div>
</template><script setup>
import { ref } from 'vue'const user = ref({ name: 'Alice', age: 25 });
const items = ref(['Apple', 'Banana', 'Cherry']);
</script>

在父组件中,使用 ​​v-slot​​ 或 ​​#​​ 语法接收:

<template><Child><template #default="{ user, items }"><p>用户:{{ user.name }}, 年龄:{{ user.age }}</p><ul><li v-for="item in items" :key="item">{{ item }}</li></ul></template></Child>
</template>

✅ 推荐使用 ​#default="{ ... }"​ 这种简洁写法(Vue 3)



📌 作用域插槽的典型应用场景(附例子)


✅ 场景 1:​​列表组件(父组件自定义每一项的展示)​

子组件:ItemList.vue
<template><ul><li v-for="(item, index) in items" :key="index"><!-- 把 item 数据通过作用域插槽暴露出去 --><slot :item="item" :index="index"></slot></li></ul>
</template><script setup>
defineProps(['items'])
</script>
父组件:
<template><ItemList :items="data"><template #default="{ item, index }"><span>第 {{ index }} 项:{{ item.name }}</span></template></ItemList>
</template><script setup>
import ItemList from './ItemList.vue'const data = [{ name: 'Apple' },{ name: 'Banana' },{ name: 'Cherry' }
]
</script>

🔍 ​​效果:​​ 子组件负责循环渲染列表,但每一项显示什么内容,由父组件通过插槽自定义!


✅ 场景 2:​​卡片组件(父组件自定义卡片内容)​

子组件:Card.vue
<template><div class="card"><slot :title="title" :content="content"></slot></div>
</template><script setup>
defineProps(['title', 'content'])
</script>
父组件:
<template><Card :title="'Hello'" :content="'Vue is awesome'"><template #default="{ title, content }"><h3>{{ title }}</h3><p>{{ content }}</p></template></Card>
</template>

你问的是:​​“React 怎么实现类似 Vue 的插槽(slot)的功能?”​

这是一个非常重要且实用的跨框架对比问题!🎯

在 Vue 中,​​插槽(slot)​​ 是一种非常核心的组件内容分发机制,它让​​父组件可以向子组件传递一段模板内容(UI 片段)​​,从而实现​​高复用、灵活定制的组件设计​​。

而 React ​​本身没有直接叫“插槽”的概念​​,但完全可以通过 ​​React 的组件设计模式 + props(特别是 children 和 render props)​​ 轻松实现 ​​类似 Vue 插槽的功能​​,甚至更灵活!


二、🔧 2. React 中如何实现类似 Vue “插槽” 的功能?

​React 没有 Vue 那样的 <slot>标签,但可以通过 props.children实现默认插槽,通过命名 props(如 header、main)实现具名插槽,通过函数 props(如 renderXXX)实现作用域插槽,从而达到与 Vue 插槽几乎相同的组件内容分发与定制能力,而且同样灵活强大!​


✅ 方法一:使用 childrenprops(实现默认插槽)

​React 中,父组件传递给子组件的 JSX 内容,可以通过 props.children获取!​

这相当于 Vue 的 ​​默认插槽​​。


📌 示例:React 实现默认插槽(类似 Vue 的 <slot>
子组件:Child.js
function Child(props) {return (<div><h2>这是子组件</h2>{/* React 中通过 props.children 获取父组件传入的内容 */}{props.children}</div>);
}export default Child;
父组件:App.js
import Child from './Child';function App() {return (<Child><p>🎉 这段内容就是插槽内容,会显示在子组件里的 {props.children} 位置</p></Child>);
}

🔍 ​​效果:​

父组件在 <Child>标签内写的内容,会通过 props.children渲染到子组件中,就像 Vue 的 <slot>一样。

✅ ​​这就是 React 实现 Vue 默认插槽的方式!​


✅ 方法二:实现类似 Vue 的​​具名插槽

在 Vue 中,你可以有多个具名插槽,比如:

<template><div><slot name="header"></slot><slot></slot><slot name="footer"></slot></div>
</template>

父组件可以这样传:

<Child><template v-slot:header>这是头部</template><p>这是默认内容</p><template v-slot:footer>这是页脚</template>
</Child>

✅ React 中如何实现具名插槽?

React 没有 v-slot:name,但可以通过 ​​传递对象形式的 children 或命名 props​​ 来模拟!

推荐方式:​​通过 props 传入不同区块内容(模拟具名插槽)​
子组件:Child.js
function Child({ header, main, footer }) {return (<div>{header && <header>{header}</header>}<main>{main}</main>{footer && <footer>{footer}</footer>}</div>);
}export default Child;
父组件:App.js
import Child from './Child';function App() {return (<Childheader={<h1>这是头部(类似具名插槽 header)</h1>}main={<p>这是主要内容(类似默认插槽)</p>}footer={<footer>这是页脚(类似具名插槽 footer)</footer>}/>);
}

🔍 ​​说明:​

  • 不像 Vue 那样用 <template v-slot:name>,而是​​通过 props 传入不同区块的 JSX​

  • 比如:header={<h1>...</h1>}main={<p>...</p>}footer={...}

  • 这是 React 社区中非常常见且清晰的实现具名插槽的方式 ✅


✅ 方法三:更灵活的方式 —— ​​使用 Render Props(高级用法)​

​Render Props 是一种 React 设计模式,允许你通过一个函数 prop,把渲染逻辑交给父组件控制,从而实现更灵活的“插槽”或内容分发。​

不过,对于大多数“插槽”场景,children或 ​​命名 props​​ 已经足够,​​Render Props 更适合控制渲染逻辑,而非单纯的内容分发。​

但为了完整性,简单介绍一下:

子组件:
function SlotDemo({ renderHeader, renderContent }) {return (<div>{renderHeader && renderHeader()}<main>{renderContent && renderContent()}</main></div>);
}
父组件:
<SlotDemorenderHeader={() => <h1>这是通过函数传入的头部</h1>}renderContent={() => <p>这是通过函数传入的内容</p>}
/>

🔒 ​​适用场景更复杂,比如子组件控制何时渲染、如何传参等,但代码可读性稍差,一般推荐上面 children / props 方式。​


三、🔍 3. 对比 Vue 插槽 和 React 实现方式

功能

Vue 插槽

React 实现方式

​默认插槽​

<slot></slot>

通过 props.children获取 <Child>...</Child>中的内容

​具名插槽​

<slot name="xxx"><template v-slot:xxx>

通过 props 传入不同 JSX 块:header={<h1>...}, main={...}

​作用域插槽​

<slot :data="xxx">,父组件接收数据

通过 props 传数据给父组件传入的函数或组件,比如 <slot data={data} />→ 父组件用 {data}

​灵活度​

高,语法清晰

同样高,但语法习惯不同(更灵活、更 JS 风格)

http://www.dtcms.com/a/473921.html

相关文章:

  • 对vue生命周期的理解
  • 2017民非单位年检那个网站做黄山旅游攻略景点必去
  • [笔记 自用]CAN总线通信配置
  • HTML 教程
  • 用自己服务器做网站用备案怎样在亚马逊网上开店
  • PHP操作elasticsearch7.8
  • 学校网站建设需求分析哪个小说网站可以做封面
  • 网站制作类软件推荐莆田网站格在哪里做
  • TypeScript 面试题及详细答案 100题 (21-30)-- 接口(Interface)
  • 承德网站新手怎么做网络推广
  • 6. 从0到上线:.NET 8 + ML.NET LTR 智能类目匹配实战--渐进式学习闭环:从反馈到再训练
  • 2.c++面向对象(五)
  • python中的一些运算符
  • 【嵌入式面试题】boss收集的11道,持续更新中
  • 保证样式稿高度还原
  • 网站建设 源码怎么注册公司名
  • [xboard] 34 buildroot 的overlay机制
  • 某公司站点的挖掘实战分享
  • 第三方和审核场景回调还是主动查询
  • Git基本命令的使用(超详细)
  • NC40 链表相加(二)
  • 网安面试题收集(3)
  • JetLinks设备接入的认识与理解
  • 从HashMap到ConcurrentHashMap深入剖析Java并发容器的演进与实战
  • 做一组静态页面网站多少钱网站源码上传到哪个文件夹
  • 威海市城乡建设局网站网络整合营销服务商
  • 从报头到路由器——【网络编程】详解 IP 协议:报头字段、路由器功能、网段划分和分片传输
  • 网站验证北京建网站开发
  • 设计模式篇之 装饰器模式 Decorator
  • 虚幻引擎虚拟制片入门教程 之 创建项目及启用插件