在项目中,我在不同的页面会使用相同样式的代码,为了避免写多处重复的代码,也避免后期多处维护的弊端,我们可以将相同样式的代码自定义封装成组件,在不同的页面调用自定义组件即可。
1、先封装自定义组件
1)、新建CardList文件夹
2)、在CardList文件夹里新建index.js文件,并在index.js文件里书写如下代码:
//index.js暴露组件CardList
import Card from './card';
import CardList from './cardList';
CardList.Card = Card;
export default CardList;
3)、在CardList文件夹里新建cardList.js文件,并在该文件下书写如下代码:
import { Component } from 'react';
import withRouter from 'umi/withRouter';
import style from './index.css';
* CardList组件内容
* @param title 组件标题
* @param extra 描述
* @param children 内容
* @param restProps 传入的自定义属性
* @returns {*}
* @constructor
const CardList = ({title, extra, children, ...restProps})=>{
return(
<div className={style.card2} {...restProps}>
<nav>{title} <span className={style.details}>{extra}</span></nav>
{React.Children.map(
children,
child => (child ? React.cloneElement(child, { }) : child)
export default CardList;
4)、在CardList文件夹里新建index.css文件,并在该文件里书写样式
.card2{
height: auto;
background-color: white;
padding: 16px;
border-bottom: 1px solid #ddd;
.card2 nav{
color: red;
text-align: left;
font-family: 'Arial Normal', 'Arial';
font-weight: 400;
font-style: normal;
font-size: 16px;
color: #333333;
margin-bottom: 0.2rem;
.card2 div{
color: #999999;
font-family: 'Arial Normal', 'Arial';
font-weight: 400;
font-style: normal;
font-size: 14px;
.list1{
text-align: left;
display: flex;
.list1>span{
/*width: 50%;*/
display: inline-block;
vertical-align: top;
/*white-space:nowrap;*/
/*overflow:hidden;*/
/*text-overflow : ellipsis;*/
flex: 1;
.details{
float: right;
color:#2DA9FA;
5)、在CardList文件夹里新建card.js文件,并在该文件下书写如下代码:
import { Component } from 'react';
import withRouter from 'umi/withRouter';
import style from './index.css';
* 子组件内容
* @param title 标题
* @param children 内容
* @param restProps 传入的自定义属性
* @returns {*}
* @constructor
const Card = ({title,children,...restProps})=>{
return(
<div className={style.list1} {...restProps}>
<span>{title} {children}</span>
export default Card;
6)、用法如下:
import { Component } from 'react';
import withRouter from 'umi/withRouter';
import router from 'umi/router';
import CardList from './CardList/index';
const {Card} = CardList;
class Index extends Component{
state ={
loading:false,
totalList:[{"trainCount":2360,"stationName":"北京"},{"trainCount":152,"stationName":"北京东"},{"trainCount":4248,"stationName":"北京南"},{"trainCount":3336,"stationName":"北京西"},{"trainCount":56,"stationName":"通州"}],
render() {
let info = <div>
this.state.totalList.map((obj,index)=>{
return <CardList title={`${obj.stationName}站`} extra={<span onClick={()=>{this.jump({obj})}}>查看当天数据</span>} key={index}>
<Card title="当天进站列车:">{obj.trainCount||0} 车次</Card>
</CardList>
return (
{info}
export default withRouter(Index);
7)、效果如下:
自定义组件
在项目中,我在不同的页面会使用相同样式的代码,为了避免写多处重复的代码,也避免后期多处维护的弊端,我们可以将相同样式的代码自定义封装成组件,在不同的页面调用自定义组件即可。1、先封装自定义组件1)、新建CardList文件夹2)、在CardList文件夹里新建index.js文件,并在index.js文件里书写如下代码://index.js暴露组件CardListimport ...
对于网页系统来说,表单提交是一种很常见的与用户交互的方式,比如提交订单的时候,需要输入收件人、手机号、地址等信息,又或者对系统进行设置的时候,需要填写一些个人偏好的信息。 表单提交是一种结构化的操作,可以通过封装一些通用的功能达到简化开发的目的。本文将讨论Form表单组件设计的思路,并结合有赞的ZentForm组件介绍具体的实现方式。本文所涉及的代码都是基于React v15的版本。
Form组件功能
一般来说,Form组件的功能包括以下几点:
封装表单验证&错误提示
下面将对每个部分的实现方式做详细介绍。
常用的表单布局一般有3种
我们可以知道,Form.getFieldDecorator会为下层组件传递一个value和onChange事件
所以在看了官网介绍后,封装自定义输入(不只是输入,级联选择等等)就很简单了
我们先在界面中写一个父组件
写一个自定义的子组件
在子组件中输入内容
其实这就相当于antd封装...
自己在react-native第三方组件库基础之上再次封装的一些组件集,供日常开发使用,大大提高开发效率。
初步形成规模,组件不复杂,易于使用,暴露的属性尽量少,便于顺利嵌入后期公司编写的自动化生成代码中。
使用typescript编写,嵌入第三方组件库,进行再开发,有兴趣可移步至:
https://github.com/HY88883/react-native-common-components
后期会进行维护更新,有可能进行hook重构。
环形进度条
首先定义一个模态框组件的类,关于模态框内部的样式布局我们在这里面写
在父组件中定义控制模态框状态的,以及我们模态框中的标题内容等,在父组件中引入模态框组件时把模态框中需要的内容传入
在父组件中定义控制模态框显示状态的方法,如打开模态框,关闭模态框等,将关闭模态框的函数也传入子组件,在子组件中取消和关闭等组件的点击事件绑定我们传入的关闭模态框函数,实现模态框的打开和关闭
实现模态框打开关闭的过渡动画效果
全部CSS代码
模态框组件代码
主界面...
2. 在 Pagination 组件内部,通过计算得到页码列表,例如显示当前页码前后各 3 页,可以使用一个循环来生成页码列表数组。
3. 在 JSX 中渲染页码列表,并添加页码点击事件,当点击页码时,调用 onChange 回调函数,并将点击的页码传递给它。
4. 在父组件中使用 Pagination 组件,并在 onChange 回调函数中更新当前页码,例如使用 useState Hook 来保存当前页码,并在 useEffect Hook 中监听 currentPage 的变化,当 currentPage 改变时重新请求数据。
5. 在请求数据时,需要将当前页码传递给后端,例如将 currentPage 作为查询参数发送给后端 API。
下面是一个简单的 Pagination 组件实现示例:
```javascript
import React, { useState, useEffect } from 'react';
function Pagination({ currentPage, totalPages, onChange }) {
const [pageList, setPageList] = useState([]);
useEffect(() => {
const list = [];
const maxPages = Math.min(totalPages, currentPage + 3);
const minPages = Math.max(1, currentPage - 3);
for (let i = minPages; i <= maxPages; i++) {
list.push(i);
setPageList(list);
}, [currentPage, totalPages]);
const handleClick = (page) => {
if (onChange) {
onChange(page);
return (
<div className="pagination">
<button disabled={currentPage === 1} onClick={() => handleClick(currentPage - 1)}>Prev</button>
{pageList.map((page) => (
<button key={page} className={page === currentPage ? 'active' : ''} onClick={() => handleClick(page)}>{page}</button>
<button disabled={currentPage === totalPages} onClick={() => handleClick(currentPage + 1)}>Next</button>
export default Pagination;
在父组件中使用 Pagination 组件:
```javascript
import React, { useState, useEffect } from 'react';
import Pagination from './Pagination';
function App() {
const [currentPage, setCurrentPage] = useState(1);
const [totalPages, setTotalPages] = useState(1);
const [data, setData] = useState([]);
useEffect(() => {
fetchData();
}, [currentPage]);
const fetchData = async () => {
const response = await fetch(`/api/data?page=${currentPage}`);
const result = await response.json();
setData(result.data);
setTotalPages(result.totalPages);
const handlePageChange = (page) => {
setCurrentPage(page);
return (
{data.map((item) => (
<div key={item.id}>{item.title}</div>
<Pagination currentPage={currentPage} totalPages={totalPages} onChange={handlePageChange} />
export default App;