文章29 | 阅读 13246 | 点赞0
在Vue中,假如我们需要让子组件的一部分内容,被父组件控制,而不是被子组件控制,那么我们会采用插槽的写法 <slot></slot>
在 React 里也有类似的写法,父组件写法是相同的,但子组件是采用 {this.props.children}
来实现。
示例:
class MyChild extends React.Component {
render() {
return <div>
{this.props.children}
</div>
}
}
class WelcomeDialog extends React.Component {
constructor(props) {
super(props)
this.state = {
date: (new Date()).toLocaleTimeString()
}
setInterval(() => {
// 显示内容全部由父组件控制,子组件不关心父组件显示什么,只关心显示在哪里
this.setState({
date: (new Date()).toLocaleTimeString()
})
}, 1000)
}
render() {
return <div>
<MyChild>
{this.state.date}
</MyChild>
</div>
}
}
如上代码,子组件展现的内容,是父组件中,子组件标签内含的内容。
关于 this.props.children
这个变量:
以<MyChild>
为例,注意,这个名字只跟子组件名挂钩,不是固定的。
<MyChild>
标签内是一个普通的字符串;<MyChild>
标签内是一个 DOM 元素,例如:<MyChild> <span>{this.state.date}</span> </MyChild>
;<MyChild>
标签内是多个 DOM 元素,例如:<MyChild> <span>{this.state.date}</span> <span>{this.state.date}</span> </MyChild>
;如何获取 <MyChild>
标签内的二级或者更多级元素?
以以下为例:
<MyChild>
<div>
abc
<span>{this.state.date}</span>
</div>
</MyChild>
abc
和一个 span
标签;this.props.children.props.children
来获取(第一个 children 指传递进来的元素,第二个指二级元素);this.props.children.props.children
在以上情况下,是一个数组,数组元素一是字符串 abc,数组元素二,是对象(即 span
标签);示例代码:
class MyChild extends React.Component {
constructor(props) {
super(props)
console.log(this.props)
}
render() {
return <div>
父元素的第一个字符串:{this.props.children.props.children[0]}
<br/>
父元素的第二个字符串:{this.props.children.props.children[1]}
</div>
}
}
class WelcomeDialog extends React.Component {
constructor(props) {
super(props)
this.state = {
date: (new Date()).toLocaleTimeString(),
year: (new Date()).toLocaleDateString()
}
setInterval(() => {
// 显示内容全部由父组件控制,子组件不关心父组件显示什么,只关心显示在哪里
this.setState({
date: (new Date()).toLocaleTimeString(),
year: (new Date()).toLocaleDateString()
})
}, 1000)
}
render() {
return <div>
<MyChild>
<div>
{this.state.date}
{this.state.year}
</div>
</MyChild>
</div>
}
}
当然,如果是纯字符串的话,通过变量 props 直接传入更好一些。
而以上这种写法,更适合传 JSX 语法的 DOM 元素。
我们有时候会面临这样一个情况:
在往常情况下,我们是这么解决的:
示例略。
这种写法,讲道理说,对于一般项目来说,也足够了,优化程度也不差;
但毕竟还有更好的写法,先提思路:
附代码(结尾见解释):
// 基础组件
class BaseInput extends React.Component {
render() {
let left = {display: 'inline-block', width: '100px'}
let right = {display: 'inline-block', width: '200px', boxSizing: 'border-box'}
let DOM
let changeFn
if (this.props.onChange) {
changeFn = e => {
this.props.onChange(e)
}
} else {
changeFn = () => {
}
}
// 首先,根据类型选择需要的输入框
if (this.props.type === 'input' | !this.props.type) {
DOM = <span>
<span style={left}>{this.props.label}</span>
<input style={right} type="text"
onChange={changeFn}
value={this.props.value}/>
</span>
} else if (this.props.type === 'textarea') {
DOM = <span>
<span style={left}>{this.props.label}</span>
<textarea style={right} type="text" onChange={changeFn}
value={this.props.value}/>
</span>
}
return <div style={{height: '50px'}}>
{DOM}
{/* 其次,允许将额外补充内容添加到这里 */}
{this.props.children}
</div>
}
}
class ChineseName extends React.Component {
constructor(props) {
super(props)
this.state = {
value: ''
}
this.verification = this.verification.bind(this)
}
verification(e) {
let v = e.target.value
// 必须是中文字符
if (/[\u4e00-\u9fa5]/.test(v)) {
this.setState({
value: v
})
}
}
render() {
return <BaseInput label={'名字'}
type={'input'}
value={this.state.value}
onChange={this.verification}>
<span style={{color: 'red'}}>只允许输入中文字符</span>
</BaseInput>
}
}
class EnglishName extends React.Component {
constructor(props) {
super(props)
this.state = {
value: ''
}
this.verification = this.verification.bind(this)
}
verification(e) {
let v = e.target.value
// 只能是英文字母和空白符
if (!/[^a-zA-Z\s]/.test(v)) {
this.setState({
value: v
})
}
}
render() {
return <BaseInput label={'英文名'}
type={'input'}
value={this.state.value}
onChange={this.verification}>
<span style={{color: 'red'}}>只允许输入a~z,或者A~Z,或者空白字符</span>
</BaseInput>
}
}
class TextareaInput extends React.Component {
render() {
return <BaseInput label={'个人情况'} type={'textarea'}>
<span style={{color: 'red'}}>请务必填写</span>
</BaseInput>
}
}
ReactDOM.render(
<div>
<ChineseName/>
<EnglishName/>
<TextareaInput/>
</div>,
document.getElementById('root')
)
说明:
verification
给基础组件,基础组件负责管理什么时候调用他;更好的优化方法:
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/qq20004604/article/details/79318239
内容来源于网络,如有侵权,请联系作者删除!