** 欢迎来到我的博客**
**📔博主是一名大学在读本科生,主要学习方向是前端。
🍭目前已经更新了【Vue】、【React–从基础到实战】、【TypeScript】等等系列专栏
🛠目前正在学习的是🔥R e a c t 框架 React框架 React框架🔥,中间穿插了一些基础知识的回顾
🌈博客主页👉codeMak1r.小新的博客**
😇本文目录😇
本文被专栏【React–从基础到实战】收录
🕹坚持创作✏️,一起学习📖,码出未来👨🏻💻!
Todos - Mobx - 综合案例
- 渲染列表数据
- 单选功能
- 全选功能
- 删除功能
- 回车新增功能
- 统计计数功能
项目目录:
src ├─App.jsx ├─index.js ├─store | ├─index.js | └task.Store.js ├─Todo | ├─index.css | └index.jsx
1.渲染列表
/src/store/task.Store.js
import{ makeAutoObservable }from"mobx";classTaskStore{constructor(){makeAutoObservable(this)}
list =[{id:1,name:'学习react',isDone:true},{id:2,name:'搞定mobx',isDone:true}]}export{ TaskStore }
/src/store/index.js
import React,{ useContext }from"react";import{ TaskStore }from"./task.Store";// 1.声明一个rootStoreclassRootStore{constructor(){this.taskStore =newTaskStore()}}// 2.实例化rootStore注入contextconst rootStore =newRootStore()const context = React.createContext(rootStore)// 3.导出useStore方法,供组件通过调用该方法使用根实例constuseStore=()=>useContext(context)export{ useStore }
/src/Todo/index.js
import{ observer }from'mobx-react-lite'import{ useStore }from'../store'import'./index.css'functionTask(){const{ taskStore }=useStore()return(<section className='todoapp'><header className='header'><h1>todos</h1>{/* 新增输入框 */}<input className='new-todo' autoFocus autoComplete='off' placeholder='What needs to be done?'/></header><section className='main'>{/* 全选 */}<input type="checkbox" id='toggle-all' className='toggle-all'/><label htmlFor="toggle-all"></label><ul className='todo-list'>{/* completed类名 */}{
taskStore.list.map((todoObj)=>{return<li key={todoObj.id} className={todoObj.isDone ?'todo completed':'todo'}><div className='view'><input id={todoObj.id} type="checkbox" className='toggle'
defaultChecked={todoObj.isDone ?true:false}/><label htmlFor={todoObj.id}>{todoObj.name}</label><button className="destroy"></button></div></li>})}</ul></section><footer className='footer'><span className="todo-count">
任务总数:{2} | 已完成: {1}</span></footer></section>)}exportdefaultobserver(Task)
使用的是Mobx中的响应式数据,用数组的map方法对数据进行遍历,之后渲染在组件中。
2.单选功能实现
首先要给Task组件声明一个自己的数据。(Mobx)
思想:通过Mobx中的store去维护状态,input只需要把event.target.checked交给store让它进行修改
- 给
task.Store.js
添加一个修改单选框选中与否的方法(修改对应id的isDone)
// 单选操作singleCheck(id, isDone){// 通过id修改对应的isDoneconst todoObj =this.list.find(item=> item.id === id)
todoObj.isDone = isDone
}
- 在
/src/Todo/Task.jsx
组件中,点击单选框触发onChange
事件,调用store中的singleCheck
方法。
{/* 单选受控 */}{/* 通过Mobx中的store去维护状态,input只需要把event.target.checked交给store让它进行修改 */}<input id={todoObj.id} type="checkbox" className='toggle'
checked={todoObj.isDone}
onChange={event=> taskStore.singleCheck(todoObj.id, event.target.checked)}/>
3.全选功能实现
思想:除了在store中需要定义全选方法,还需要通过Mobx的计算属性定义一个是否所有项都被选中与否的方法,如果所有项都被选中,那么点击全选按钮可以变为全不选;如果不是所有项都被选中,那么点击全选按钮变为全选。
- 给
task.Store.js
添加一个全选/全不选方法。
// 全选操作allCheck(checked){// 把所有项的isDone属性,都按照传入的最新的值修改this.list.map(item=>{
item.isDone = checked
})}
- 给
task.Store.js
定义计算属性isAllDone
,当所有的项都被选中时,这个属性为true;否则为false。
// 计算属性 只有所有子项都是选中的时候,才是选中的状态getisAllDone(){returnthis.list.every(item=> item.isDone)}constructor(){-makeAutoObservable(this)+makeAutoObservable(this,{isAllDone: computed
})}
- 在
/src/Todo/Task.jsx
组件中,点击全选框,进行全选与全不选之间的改动
{/* 全选 */}<input type="checkbox" id='toggle-all' className='toggle-all'
checked={taskStore.isAllDone}
onChange={()=> taskStore.allCheck(!taskStore.isAllDone)}/>
4.删除功能实现
思想:在store中定义删除方法,使用filter数组方法,删除对应id的那一组数据
- 给
task.Store.js
添加删除的方法
// 删除操作delTask(id){this.list =this.list.filter(item=> item.id !== id)}
- 在
/src/Todo/Task.jsx
组件中点击删除按钮,删除对应那一行的todo。
<button className="destroy" onClick={()=> taskStore.delTask(todoObj.id)}></button>
5.回车新增功能实现
*思想:在组件中使用useState-hook,用于临时存放一下新增输入框的value内容。之后,在按下
Enter
之后,调用store中定义的新增方法,实现新增功能。*
- 给
task.Store.js
添加新增的方法
// 新增操作insertTask(task){this.list.push(task)}
- 在组件中,使用
useState
临时存放输入框的value值。
// 存放新增的todoconst[taskValue, setTaskValue]=useState('')// 新增输入框<input className='new-todo' autoFocus autoComplete='off' placeholder='What needs to be done?'
value={taskValue} onChange={event=>setTaskValue(event.target.value)}/>
其实也就是受控组件一样的写法,把输入框与taskValue这个临时state绑定。
- 按下
Enter
实现新增。
// 为input添加属性
onKeyUp={event=>addTask(event)// 定义addTask方法functionaddTask(event){if(event.keyCode !==13)returnif(taskValue.trim()===''){alert('输入不能为空!')return}
taskStore.insertTask({id:nanoid(),// 使用第三方库nanoid自动生成随机的id值name: taskValue,isDone:false})setTaskValue('')}
6.统计计数功能实现
任务总数很简单,其实就是list数组的长度。
{taskStore.list.length}
已完成的数量需要借助
Mobx
中的计算属性来完成具体代码如下:
- 在
task.Store.js
中定义计算属性isFinishedLength
// 已完成的数量getisFinishedLength(){returnthis.list.filter(item=> item.isDone).length
}constructor(){makeAutoObservable(this,{isAllDone: computed,+ isFinishedLength: computed
})}
- 渲染
{taskStore.isFinishedLength}
7.Mobx - React 职责划分
版权归原作者 codeMak1r.小新 所有, 如有侵权,请联系我们删除。