最好的方法来改变vue插槽模式到React?

zwghvu4y  于 2023-03-09  发布在  Vue.js
关注(0)|答案(3)|浏览(139)

在我的vue应用程序中,我使用slots来处理一些内容块。现在,我必须将我的应用程序迁移到react中。在探索react的过程中,我了解到props.children的工作原理与slots works类似。
但是,我不确定在react中使用此模式的正确方式是什么。

以下是vue中的代码示例

<template>
    <div class="badge-box">
        <span :class="badgeClass" :style="badgeStyle">
            <span v-if="shape !=='dot'" class="line-break">
                <slot>
                    {{text}}
                </slot>
            </span>
        </span>
        <span v-if="shape ==='dot'" class="line-break" style="margin-left: 8px;">
            <slot name="dotShape">
                {{text}}
            </slot>
        </span>
    </div>
</template>

<script>
 export default {
   name:'sample'
   props: {
     text: { type: string }
   
   }
 
 }
</script>

如何使用 prop 将这个模式转换成React模式?

uinbv5nw

uinbv5nw1#

React中有几种模式与Vue插槽密切相关。
可以使用props.children,但仅限于没有slotPropsdefault槽。对于命名槽,可以使用附加 prop 。默认槽内容<slot>{{text}}</slot>可以在没有提供子项时有条件地呈现:

let MyComp = props => (
  ...
  <div class="default-slot">{{props.children ?? props.text}}</div>
  ...
  <div class="named-slot">{{props.named ?? props.text}}</div>
  ...
)

以及

<MyComp named={<p>Named content</p>}>
  <p>Default content</p>
</MyComp>
  • Function as child* 和 function as prop 模式的作用相同,但允许用slotProps替换slot。子作用域可以通过回调向父作用域传递参数:
let MyComp = props => (
  ...
  <div class="default-slot">{{props.children?.('foo') ?? props.text}}</div>
  ...
  <div class="named-slot">{{props.named?.('bar') ?? props.text}}</div>
  ...
)

以及

<MyComp named={param => <p>Named content {{param}}</p>}>{
  param => <p>Default content {{param}}</p>
}</MyComp>
3hvapo4f

3hvapo4f2#

Vue插槽可以相当容易地复制。
下面是一个向父组件公开对象的 named 插槽的示例。

function Parent() {
  return (
    <div>
      <Child slot={(slotItemData: any) => <div>Message: {slotItemData.message}</div>}></Child>
    </div>
  );
}

function Child(props: any) {
  let slotItemData = {
    message: "Hello form child",
  };

  return <div>{props.slot?.(slotItemData)}</div>;
}

留言:您好,来自孩子

pw9qyyiw

pw9qyyiw3#

假设您在函数React中使用JSX/TSX

const Component ({text}) => {
    return (
        <div class="badge-box">
            <span :class="badgeClass" :style="badgeStyle">
                <span v-if="shape !=='dot'" class="line-break">
                    {{text}}
                </span>
            </span>
            <span v-if="shape ==='dot'" class="line-break" style="margin-left: 8px;">
                {{text}}
            </span>
        </div>
    )
}

将做你想做的。如果你使用类组件,把它放在render方法中。

相关问题