主题
Props
在 Vue 中,为了提升开发体验,框架将组件接收的外部信息拆分成了多个专有概念;而在 React 中,除了 ref 和 key 两个特殊属性外,所有从父组件流向子组件的数据、配置、甚至结构,统称为 Props。
| 功能 | Vue 的实现方式 | React 的实现方式 (全部通过 Props) |
|---|---|---|
| 自定义数据 | props: { msg: String } | props.msg |
| 原生属性 | $attrs (自动挂载或手动绑定) | 直接透传给 HTML 标签的 props |
| 样式处理 | class / style (特殊处理) | className / style (普通对象 Prop) |
| 事件监听 | @click / emit | onClick (回调函数 Prop) |
| 插槽 (Slots) | <slot /> / #namedSlot | children 或自定义渲染 Prop |
| 双向绑定 | v-model | value + onChange (受控组件模式) |
基本使用
注意事项:
- props 可以传递任意数据:字符串、数字、布尔值、数组、对象、函数、JSX。
- 必须遵循 单向数据流,子组件只能读取 props 中的数据,不能直接修改!
jsx
const App = () => {
return (
<>
<Son
name="小明"
age={18}
isTrue={true}
list={[1, 2, 3]}
obj={{ a: 1, b: 2 }}
onFn={(msg) => {
console.log(msg)
}}
el={<div>小明</div>}
>
<div>default</div>
</Son>
</>
)
}jsx
const Son = (props) => {
console.log(props)
return <div onClick={() => props.onFn('son')}>子组件</div>
}prop-types
prop-types 是一个用于类型检查的库,可以帮助开发者在开发过程中捕获错误,确保组件接收到正确类型的 props。
安装
bash
npm i prop-types使用
tsx
import PropTypes from 'prop-types'
interface PropsType {
name: string
sex: string
age: number
}
function Card(props: PropsType) {
const { name, sex, age } = props
return (
<div>
<p>姓名:{name}</p>
<p>性别:{sex}</p>
<p>年龄:{age}</p>
</div>
)
}
Card.propTypes = {
name: PropTypes.string.isRequired,
sex: PropTypes.string,
age: PropTypes.number,
}
Card.defaultProps = {
sex: '男',
age: 18,
}
export default CardEmit
提示
可类比于 vue 中的 emit。
jsx
import { useState } from 'react'
import AnswerButton from './AnswerButton'
function App() {
const [isHappy, setIsHappy] = useState(true)
const onAnswerNo = () => {
setIsHappy(false)
}
const onAnswerYes = () => {
setIsHappy(true)
}
return (
<>
<p>Are you happy?</p>
<AnswerButton onYes={onAnswerYes} onNo={onAnswerNo} />
<p style={{ fontSize: 50 }}>{isHappy ? '😀' : '😥'}</p>
</>
)
}
export default Appjsx
function AnswerButton({ onYes, onNo }) {
return (
<>
<button onClick={onYes}>YES</button>
<button onClick={onNo}>NO</button>
</>
)
}
export default AnswerButtonSlot
提示
可类比于 vue 中的 slot。
children
当把内容嵌套在子组件标签中时,父组件会自动在名为 children 的属性中传递进来。
jsx
const App = () => {
return (
<Son>
<div>小明</div>
</Son>
)
}jsx
function Son(props) {
return <div>{props.children}</div>
}直接传递 JSX
jsx
const App = () => {
return <Card header="标题" body="内容" footer="底部" />
}jsx
const Card = (props) => {
return (
<div>
<div className="header">{props.header}</div>
<div className="body">{props.body}</div>
<div className="footer">{props.footer}</div>
</div>
)
}