构造复合型组件

xiaoxiao2021-02-28  46

上篇文章中,已使用组件技术,实现了一个“五彩冰粉”的网页控件。 从中可以体会到,组件其实就是把html, javascript, 和css 以有机的方式结合在一起,形成一个高度可重用的独立单元

本篇文章中,将研究组件的另一特性,就是它的组合性,React组件 技术的一大杀伤力在于,它能让我们通过把微小简单的组件结合起来,进而创造出复杂强大的复合组件,

把控件分解成 若干个简单的控件,然后把这些简单小控件组合起来,最终形成我 们想要的页面组件,调色板控件如图,在文本框中输入颜色的数值,点击 回车,文本框上面的小版块就会改变成文本框中输入的数值相一致 的颜色

我们可以把这个控件分成两部分,一部分是上面用于显示颜色的 小方块,我们可以称之为显色板,另一部分就是下边的文本输入框 。于是,要完成这个控件,我们需要完成三个步骤:

1, 创建一个控件,用于实现显色板 

2, 创建一个控件,用于实现文本输入框 

3, 将两个控件有机结合起来

在代码中创建三个组件,第1个组件用来构建显色板,我们把它 命名为square,

 第2个组件对应的是文本输入框,我们把它命名为 label, 

第三个组件作用是把前两个组件整合起来,形成我们最终 想要的控件。代码如下:

<script type="text/babel"> var destination = document.querySelector("#container"); var Square = React.createClass({ render:function() { return ( <p>This is a square</p> ); } }); var Label = React.createClass({ render:function() { return ( <p>This is a label</p> ); } }); var Card = React.createClass({ render: function() { var cardStyle = { height:200, width:150, padding:0, backgroundColor:"#FFF", WebkitFilter:"drop-shadow(0px 0px 5px #666)", filter: "drop-shadow(0px 0px 5px #666)" }; return ( <div style={cardStyle}> <Square/> <Label/> </div> ) } }) ReactDOM.render( <div> <Card/> </div>, destination ); </script>

上篇文章提到过,React在设计控件样式时,可以把原来css的 设计属性转变为js的json对象,与控件的业务逻辑放到一起。 这里我们需要注意一个属性叫WebkitFilter, 该属性与我们以前 提到的命名机制不一样,我们以前说,属性的命名要采取骆驼格式 ,也就是首单词小写,第二个大小,依次类推,但这里,该属性 首个单词就大写了,这是因为这个属性是专门针对webkit内核的 浏览器的,所以,当某个属性是针对某个具体厂商开发的浏览器 时,该属性第1个单词的首字母要大写。

接下来,处理控件上面的显色板部分,同理我们先定义显色板 的显示样式,添加代码如下:

var Square = React.createClass({ render:function() { var squareStyle ={ height:150, backgroundColor:"#FF6663" } return ( <div style={squareStyle}> <p>This is a square</p> </div> ); } });

继续完善下面的文本框 输入控件:

var Label = React.createClass({ render:function() { var labelStyle = { fontFamily:"sans-serif", fontWeight:"bold", padding:13, margin:0 }; return ( <p style={labelStyle}>#FF6663</p> ); } });

完成以上代码后,整个控件的基本样式已经成型,接下来我们把 精力集中到控件的业务逻辑上

现在,控件有一个问题,就是上面显色板显示的颜色和下面文本框显示的字符,是在代码里写死的,最后要完成的控件 ,其功能是让用户输入颜色,然后显色板根据用户输入改变它该 显示的颜色。解决这个问题的办法,那就是 依赖控件的属性机制。

当前控件需要动态可变的有两部分,一部分上显色板的背景色,该 颜色需要根据用户的输入进行相应变动,另一部分是下面文本框的 输入内容。因此我们需要做的改变是将这两部分的属性设置由原来 的写死转变为从外部通过属性传递进来,因此代码做如下改变:

var Square = React.createClass({ render:function() { var squareStyle = { height:150, backgroundColor: this.props.color } return ( <div style={squareStyle}> <p>This is a square</p> </div> ); } }); var Label = React.createClass({ render:function() { var labelStyle = { fontFamily:"sans-serif", fontWeight: "bold", padding:13, margin: 0 }; return ( <p style={labelStyle}>{this.props.color}</p> ); } });

由于这两个控件间套在父控件Card的内部,因此用户如果想要把 信息传递给它们,那么信息需要先传递给父控件Card,然后通过父控件Card再次传递给这两个子控件,因此代码修改如下:

var Card = React.createClass({ render:function() { var cardStyle = { height: 200, width: 150, padding: 0, backgroundColor: "#FFF", WebkitFilter:"drop-shadow(0px 0px 5px #666)", filter: "drop-shadow (0px 0px 5px #666)" }; return ( <div style={cardStyle}> <Square color={this.props.color <Label color={this.props.color </div> ); } }); ReactDOM.render( <div> <Card color="#FF6663"/> </div>, destination );加载修改的代码后,我们可以看到显色板的颜色和下面文本框的文本已经改变了

总结:

 本节,我们我们注重的是组件的组合特性,也就是一个复杂的组件可以通过多个简单的小组件组合而成。此篇文章先观察一个最终组件是怎样的,然后倒推回去,把整个大组件分割成两个小组件的结合。

把大组件分割成小组件,分别实现每个小组件后,接下来的问题是 如何把零散的小组件组合起来,把小组件作为大组件的子控件 ,把他们间套在大控件所对应的标签中。同时需要注意到,内部控件的属性想要获得外部输入进行, 需要先把属性值提交给父控件,然后再由父控件把获得的信息转移 给它内部的子控件,内部子控件是不能直接获取外部信息的。

当前控件存在一个问题是,下面文本框不能接收收户输入, 要解决这个问题,需要研究React控件的事件响应机制,未完待续 
转载请注明原文地址: https://www.6miu.com/read-2626571.html

最新回复(0)