拆分组件: 拆分界面,抽取组件
实现静态组件: 使用组件实现静态页面效果
实现动态组件
import '.\xxx.less'
,样式采用嵌套格式,顶级样式名不重即可,建议使用组件名 .module
.module
,例如 xxx.module.css
import styles from 'xxx.module.css'
className={styles.xx}
如果要对 props 进行限制,需要引入 prop-types 库
安装指令:yarn add prop-types
引入指令:import PropTypes from 'prop-types'
使用限制:static propTypes = { addOne: PropTypes.func.isRequired }
使用可参考 五、【React基础】组件实例三大核心属性之二 props 中 2、3 栏
id 需要使用不重复随机数,推荐使用nanoid
安装指令:yarn add nanoid
引入函数:import { nanoid } from 'nanoid'
使用函数:nanoid()
只有红框内的文件有修改或是新增的
import React, { Component } from 'react'
import { nanoid } from 'nanoid'
import Header from './components/ToDoList/Header'
import List from './components/ToDoList/List'
import Footer from './components/ToDoList/Footer'
import './App.css'export default class App extends Component {state = {todoList: [{id: '001',name: '吃饭',done: false}, {id: '002',name: '睡觉',done: false}, {id: '003',name: '打豆豆',done: false}]}toNever = id => {const { todoList } = this.statetodoList.map(item => {if (item.id === id) {item.done = !item.done}return item})this.setState({ todoList })}addOne = name => {const { todoList } = this.statethis.setState({todoList: [{id: nanoid(),name,done: false},...todoList]})}deleteById = id => {if (!window.confirm('确定删除吗?')) returnconst { todoList } = this.statethis.setState({ todoList: todoList.filter(item => item.id !== id) })}deleteDone = () => {if (!window.confirm('确定删除吗?')) returnconst { todoList } = this.statethis.setState({ todoList: todoList.filter(item => !item.done) })}doneAllOrNot = () => {const { todoList } = this.stateconst dones = todoList.filter(i => i.done).lengthtodoList.map(item => {item.done = !(todoList.length === dones)return item})this.setState({ todoList })}render() {return (this.addOne} />...this.state} toNever={this.toNever} deleteById={this.deleteById} />
);}
}
/*base*/
body {background: #fff;
}.btn {padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;
}.btn-danger {color: #fff;display: none;background-color: #da4f49;border: 1px solid #bd362f;
}.btn-danger:hover {color: #fff;background-color: #bd362f;
}.btn:focus {outline: none;
}.todo-container {width: 600px;margin: 0 auto;
}.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;
}/*header*/
.todo-header input {width: 560px;height: 28px;font-size: 14px;border: 1px solid #ccc;border-radius: 4px;padding: 4px 7px;
}.todo-header input:focus {outline: none;border-color: rgba(82, 168, 236, 0.8);box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
}/*main*/
.todo-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;
}.todo-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;border-radius: 2px;padding-left: 5px;margin-top: 10px;
}/*item*/
li {list-style: none;height: 36px;line-height: 36px;padding: 0 5px;border-bottom: 1px solid #ddd;display: flex;justify-content: space-between;
}li label {float: left;cursor: pointer;
}li label li input {vertical-align: middle;margin-right: 6px;position: relative;top: -1px;
}li button {float: right;display: none;margin-top: 3px;
}li:hover .btn {display: block;
}li:before {content: initial;
}li:last-child {border-bottom: none;
}/*footer*/
.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;
}.todo-footer label {display: inline-block;margin-right: 20px;cursor: pointer;
}.todo-footer label input {position: relative;top: -1px;vertical-align: middle;margin-right: 5px;
}.todo-footer button {float: right;margin-top: 5px;
}.todo-footer:hover .btn {display: block;
}
import React, { Component } from 'react'
import PropTypes from 'prop-types'export default class Header extends Component {static propTypes = {addOne: PropTypes.func.isRequired}add = e => {const { addOne } = this.propsif (e.key === 'Enter') {if (!!e.target.value.trim()) {addOne(e.target.value)e.target.value = ''} else {alert('请输入非空任务名')}}}render() {return (this.add} />)}
}
import React, { Component } from 'react'
import Item from './Item'export default class List extends Component {render() {const { todoList, toNever, deleteById } = this.propsreturn ({todoList.map(item => - item.id} todo={item} toNever={toNever} deleteById={deleteById} />)}
)}
}
import React, { Component } from 'react'export default class Item extends Component {render() {const { id, name, done } = this.props.todoconst { toNever, deleteById } = this.propsreturn ()}
}
import React, { Component } from 'react'export default class Footer extends Component {render() {const { todoList, doneAllOrNot, deleteDone } = this.propsconst total = todoList.lengthconst done = todoList.filter(item => item.done).lengthreturn (已完成{done || 0} / 全部{total || 0})}
}
小白学习参考视频:尚硅谷React教程
中文官网:React 官方中文文档
上一篇:赞美技术员的句子
下一篇:如何取消QQ空间的10句话?求助