思维图
前面的
1)在实际开发中,我们抽取了一个组件,为了让这个组件具备更强的通用性,我们不能将组件中的 子元素写死固定的div、span等等这些元素;
2)我们应该让使用者可以决定某一块区域到底存放什么内容;
3)比如 Vue 中有一个插槽的概念,可以任意放置内容;
一、搭建Demo项目
1. 首先,我们将代码中的一些无用代码都删除掉,只留下index.js 和 App.js 即可;
2. 新建 NavBar.js 和 NavBar2.js 文件,因为有两种实现方式,所以新建两个组件引用在App.js;
import React, { Component } from 'react';
import NavBar from './NavBar';
import NavBar2 from './NavBar2';
export default class App extends Component {
render() {
return (
<div>
<NavBar></NavBar>
<NavBar2 />
</div>
)
}
}
3. 新建 nav-bar.style.css 文件用来编写NavBar组件的样式;
body {
padding: 0;
margin: 0;
}
.nav_bar {
display: flex;
margin-bottom: 20px;
}
.nav_bar div {
text-align: center;
height: 40px;
line-height: 40px;
}
.nav_center {
flex: 1;
background-color: sandybrown;
}
.nav_left, .nav_right {
width: 50px;
background-color: rosybrown;
}
二、通过props.children方式实现
//App.js
import React, { Component } from 'react';
import NavBar from './NavBar';
export default class App extends Component {
render() {
return (
<div>
<NavBar>
<span>left</span>
<em>center</em>
<a href="/#">right</a>
</NavBar>
</div>
)
}
};
//NavBar.js
import React, { Component } from 'react';
import './nav-bar.style.css';
export default class NavBar extends Component {
render() {
// console.log(this.props)
return (
//1.通过children的索引方式取出,但是不保序。
<div className="nav_bar">
<div className="nav_left">
{this.props.children[0]}
</div>
<div className="nav_center">
{this.props.children[1]}
</div>
<div className="nav_right">
{this.props.children[2]}
</div>
</div>
)
}
};
注意: 如果children中有多个元素, 那么children是一个数组, 例如上面数组中存放着0、1、2三项元素; 如果只插入一个元素 <NavBar><div>哈哈哈</div></NavBar> 到子组件中, 那么children(对象)本身就是插入的该元素{this.props.children};
三、通过props数据的方式传递实现
//App.js
import React, { Component } from 'react';
import NavBar2 from './NavBar2';
export default class App extends Component {
render() {
return (
<div>
{/*2. 通过数据的方式传递 */}
<NavBar2
leftSlot={<span>left</span>}
centerSlot={<em>center</em>}
rightSlot={<a href="/#">right</a>}
/>
</div>
)
}
};
import React, { Component } from 'react';
import './nav-bar.style.css';
export default class NavBar extends Component {
render() {
// console.log(this.props);
const { leftSlot, centerSlot, rightSlot } = this.props;
return (
<div className="nav_bar">
<div className="nav_left">
{leftSlot}
</div>
<div className="nav_center">
{centerSlot}
</div>
<div className="nav_right">
{rightSlot}
</div>
</div>
)
}
};
四、效果
两种实现方式的效果都是一样的;
最后的
写Vue多了会发现props.children方式实现比较好理解,但是存在缺陷:父组件转的时候需要考虑顺序问题,子组件在展示的时候需按照顺序取放,顺序不可以错误,代码不宜读;
另一种方式是通过传值的方式,将 JSX 代码传递过去,并且使用 leftSlot、centerSlot 等语义化变量使代码变的易读,子组件只关心放的位置;
当你犹豫选择哪条路时,可能已经启程了好一阵。