基于 React 的一个简单 Todo-list
先赌为快: 在线 DEMO, 感觉还不错点一下 star -_- ~
源码地址 https://github.com/ZWLTZ/react-todo :
一, 已经完成的功能
1, 新增选项 (默认未完成)
2, 完成状态可以切换
3, 当前选项可以删除
4, 全部选项选中状态切换
5, 全部个数, 完成个数, 未完成个数实时读取
6, 刷新状态不变
7, 双击可以编辑 (有个坑: 双击编辑内 input 的 keyUp Enter 保存会连带触发 blur 失去焦点保存. 已解决: 通过设置一个可以保存的状态控制)
二, 待完成 (新增路由)
三, 目录结构
3.1, 主要逻辑只涉及: Todo(父组件),TodoAdd(输入框子组件一),TodoList(选项列表子组件二)
3.2, 父子组件通过 props(可以是自定义属性, 对象, 回调函数) 通信, 每个组件都有自己的 state, 可以通过 setState 改变当前的 state.
例如: 新增的时候, 父组件是如何知道新增了一个什么内容呢? 如下:
- // Todo.jsx 内
- //1 传递给子组件的回调函数, 只要有心得内容传递过来, 就更新当前的: list.list 只要更新, 通过 props 传递给 TodoList 的 data 就会更新, DOM 就会新增一个选项列表
- onAddSubmit(addTitle) {
- console.log("增加了:" + addTitle)
- let addItem = {
- title: addTitle,
- isFinished: false
- }
- this.state.list.unshift(addItem)
- this.setState({ list: this.state.list })
- this._saveToSession()
- }
- // 通过 props 传递给子组件 (等待使用)
- <TodoAdd onAddSubmit={this.onAddSubmit} />
- // TodoAdd.jsx
- // 2, 點擊 enter 鍵: 有值就確認增加
- _onKeyUpEnter(e) {
- if (e.keyCode == 13) {
- this.confirmAddItem()
- }
- }
- // 3, 失去焦點: 有值就確認增加
- _onBlurEnter(e) {
- this.confirmAddItem()
- }
- // 4, 確認增加, 调用父组件的回调函数, 传递参数
- confirmAddItem() {
- if (this.state.title) {
- this.props.onAddSubmit(this.state.title) // 把新增的内容通过 props 传进来的回调函数告诉父组件 Todo, 有新的内容来了
- // 置空當前
- this.setState({
- title: ""
- })
- }
- }
其他: 上面这个简单的父子组件的通信过程和 es6 模块化通信非常类似, 只是 react 做了优化, 比如上面的使用 es6 来模拟如下, 只是做了通信模拟:
- // Todo.JS 父模块
- import TodoAdd from "./TodoAdd"
- import TodoList from "./TodoList"
- class Todo {
- constructor() {
- this.list = []
- this.TodoAdd = new TodoAdd({
- // 父模块给子模块的回调
- resetList: (content) => {
- if (content) {
- this._updateList(content)
- }
- }
- })
- this.TodoList = new TodoList({
- list: this.list,
- })
- }
- _updateList(content) {
- this.list.push(content)
- // 调用子模块的方法更新内部列表
- this.TodoList && this.TodoList._getNewList(this.list)
- }
- }
- module.exports = Todo
- // TodoAdd.JS 新增子模块
- class TodoAdd {
- constructor({
- resetList,
- }) {
- this.resetList = resetList
- }
- _onSubmit(str) {
- if (str) {
- // 1, 告诉父模块新增了
- this.resetList(str)
- }
- }
- }
- module.exports = TodoAdd
- // TodoList.JS 列表子模块
- class TodoList {
- constructor({
- list,
- }) {
- this.list = []
- this._getNewList(list)
- }
- // 3, 监听父模块是否要更新
- _getNewList(newList) {
- this.list = newList
- // 其他操作
- }
- }
- module.exports = TodoList
来源: https://www.jb51.net/article/143376.htm