Taro多端开发权威指南:小程序、H5与App高效开发实战
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.2 组件化

长期以来,前端开发者都在探索如何更好地管理项目模块,都在思考如何设计各模块中类似的UI及逻辑以达到高效复用的目的。早期我们通过定义通用代码文件,在项目中通过script标签引入方式完成复用,这种方式确实能在一定程度上实现通用代码复用、对应模块版本管理等需求,但在大型项目中,这种方式会显得很脆弱,模块之间的依赖管理能力欠缺。后来,有了Bower、Grunt、Gulp等,解决了模块文件或依赖间的控制问题。再后来,有了Webpack,有了各种模块化规范,如AMD、CMD、Commonjs、ES module等,前端开发才进入一个新的世纪。一路进化,最终组件化、MVC、面向对象编程、函数式编程等思想才得以迸发。

2.2.1 初识组件

首先来看一个例子,下图是京东商城首页,我们站在开发者的角度来分析一下这个网页的页面结构。

在使用Taro开发这个页面时,首先考虑将页面内容拆分为图中标注的6个模块,设计好模块间的数据与UI交互之后,便可以单独开发每个模块,最终组合各个模块,完成开发。这里拆解的6个部分,正是6个独立组件。

2.2.2 组件定义

Taro中的组件分为两种,一种是基于类创建的组件,被称为类组件;一种是基于函数创建的组件,被称为函数组件

1.类组件

定义类组件是一件很容易的事情,你只需要定义一个类,这个类继承自Taro.Component,且在组件中定义render方法并返回值即可,代码示例如下:

当然,还有为了做优化提供的另一种类组件,关于该组件的原理与用法,我们将在实战优化部分进行详细介绍,代码示例如下:

2.函数组件

函数组件相较于类组件,定义更便捷,使用更灵活,尤其搭配Hooks使用能够在某些场景下替代类组件。函数组件的定义如下:

或者使用箭头函数,写法如下:

注:在组件中,无论是否使用Taro这个对象,都应该将@tarojs/taro包引入。无论组件返回值多么简单,都尽量使用@tarojs/components提供的组件包裹,而不应该直接返回数字或字符串等。

定义好组件后,最终需要将最上层组件也就是根组件挂载到DOM节点上:

为了方便讲解,后续章节将统一使用类组件,当然我们也会在Hooks章节详细介绍函数组件的知识。

2.2.3 props

很多时候,组件中使用的某些数据可能需要外部提供,就像我们使用HTML中的图片标签时,需要设置src属性才能显示对应图片。假如现在定义了一个名叫Timg的类似图片img的组件,组件内部应该怎样获取外部传入的属性数据并使用呢?答案是使用props,代码示例如下:

效果如下图所示。

通过props,可以将数据传递给组件,组件内部通过this.props获取对应的属性数据,渲染即可。

有时,某些属性数据并不一定是外部必须传入的,因此我们在定义组件时,可以设置默认属性数据,如上例:

若在使用Timg组件时不传入src属性,则Timg组件会使用我们通过defaultProps设置的src属性的默认数据渲染页面。反之,Timg组件会使用外部传入的src属性数据进行渲染。

2.2.4 state

组件中还有一类数据,它具备以下几个特征:

· 数据私有,仅供组件内部使用。

· 数据需要根据某些操作发生更改,并触发视图更新。

这些特征正是组件状态state期望具备的,满足这些特征的数据一般都要考虑放入组件状态state中。

我们现在想设计一个组件,组件中有一个状态count,该值每过一秒增加1,并在增加后显示在页面中。代码设计如下:

通过这个示例,我们可以总结出state的用法:

· 类组件中有一个名叫state的预定义属性,该属性为对象,对象中记录了关于该组件的所有状态。如上例中,状态count的初始值为1。

· 在需要更改这个状态时,调用组件的setState方法,这个方法继承自Taro.Component。

· 在JSX中,通过this.state获取对应状态值并使用。

注:任何时候都不要通过赋值的形式直接修改state,如上例中,this.state.count=this.state.count+1这种赋值方式是错误的,正确的操作应该是用this.setState更新指定状态。

2.2.5 样式

看了以上与组件相关的例子,对于组件,你是否有种似曾相识的感觉?其实从某种角度来看,组件类似HTML中的标签,这样类比后,关于组件的很多问题都能迎刃而解。组件中样式的使用方法和HTML中一致,也分为两种:内联样式和外部样式。

1.内联样式

组件的内联样式通过style属性指定。与HTML标签的style属性不同的是,组件的style属性接收一个对象:

使用内联样式需要注意以下几点:

· 如果不指定尺寸单位,则会默认解析为px,如前面代码中的width:100,会被解析为width:'100px'。

· 属性名改为驼峰式命名,如background-color改为backgroundColor。

2.外部样式

外部样式可以使用CSS、Less、Sass等文件定义样式,然后在对应的模块文件中引入。我们以Less为例:

注:我们前面就有提到,因为class为JavaScript关键字,不能出现在JSX中,所以需要使用className替代class。