• 【Mobx和React的职责划分】Todos综合案例分析(附源码)


    前言

    博主主页👉🏻蜡笔雏田学代码
    专栏链接👉🏻React专栏
    之前学习了Mobx集中状态管理工具
    参考文章👉🏻【MobX集中状态管理工具】MobX真的取代了Redux吗
    今天来学习关于Mobx的一个小案例!
    感兴趣的小伙伴一起来看看吧~🤞

    在这里插入图片描述


    Todos综合案例

    效果

    在这里插入图片描述

    Mobx和React的职责划分

    在这里插入图片描述

    列表渲染

    src/Todo/index.js

    import './index.css'
    import { useStore } from '../store'
    import { observer } from 'mobx-react-lite'
    
    function Task () {
      const { taskStore } = useStore()
      
      return (
        <section className="todoapp">
          <section className="main">
            <ul className="todo-list">
              {/* 列表区域 */}
              {taskStore.list.map(item => (
                <li
                  className="todo"
                  key={item.id}
                >
                  <div className="view">
                    <input
                      className="toggle"
                      type="checkbox"
                     />
                    <label >{item.name}</label>
                    <button className="destroy"}></button>
                  </div>
                </li>
              ))}
            </ul>
          </section>
          <footer className="footer">
            <span className="todo-count">
              任务总数: {10} 已完成: {1}
            </span>
          </footer>
        </section>
      )
    }
    
    export default observer(Task)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    单选实现

    实现思路和步骤:本质上是在实现双向绑定

    1. 通过store中的数据状态 isDone字段,绑定到input元素的 checked属性上
    2. 监听事件,调用mobx的对应方法,传入id,找到要修改的项,把isDone字段取反操作

    src/store/taskStore.js

    import { makeAutoObservable } from 'mobx'
    class TaskStore {
      list = [
        {
          id: 1,
          name: '学习react',
          isDone: true
        },
        {
          id: 2,
          name: '搞定mobx',
          isDone: false
        }
      ]
      constructor() {
        makeAutoObservable(this)
      }
      // 单选操作
      singleCheck(id, isDone) {
        // 查找
        const item = this.list.find(item => item.id === id)
        item.isDone = isDone
      }
    }
    export default TaskStore
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    src/Todo/index.js

    // 单选受控
    // 思想:mobx Store去维护状态,input只需要把e.target.checked交给store让它来进行维护
    function onChange(id, e) {
      // console.log(id, e.target.checked)
      taskStore.singleCheck(id, e.target.checked)
    }
    ...
    {/* 单选框 受控和非受控 受控的方法*/}
    <input className="toggle" type="checkbox" onChange={(e) => onChange(item.id, e)} />
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    全选功能

    实现思路和步骤:

    1. 实现数据驱动权限UI显示,通过计算属性 + every方法
    2. 实现点击权限,控制所有子项,change事件拿到e.target.checked,遍历list进行isDone赋值

    src/store/taskStore.js

    // 全选操作
    allCheck(checked) {
      // 把所有项的isDone属性,都按照传入的最新的状态修改
      this.list.forEach(item => {
        item.isDone = checked
      })
    }
    
    // 计算属性 只有所有子项都是选中的时候,才是选中的状态
    get isAll() {
      return this.list.every(item => item.isDone)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    src/Todo/index.js

    // 全选
    function allChange(e) {
      taskStore.allCheck(e.target.checked)
    }
    ...
    {/* 全选框 */}
    <input 
    	id="toggle-all" 
    	className="toggle-all" 
    	type="checkbox" 
    	checked={taskStore.isAll} 
    	onChange={allChange} />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    删除功能

    实现思路和步骤:

    1. 在mobx中定义好删除数据的方法

    2. 点击删除,调用mobx提供的删除方法,传出id,进行删除

    src/store/taskStore.js

    // 删除操作
    delTask(id) {
      this.list = this.list.filter(item => item.id !== id)
    }
    
    • 1
    • 2
    • 3
    • 4

    src/Todo/index.js

    // 删除
    function delTask(id) {
      taskStore.delTask(id)
    }
    ...
    {/* 删除按钮 */}
    <button className="destroy" onClick={() => { delTask(item.id) }}></button>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    回车新增功能

    实现思路和步骤:

    1. 在mobx中编写新增方法的逻辑
    2. 在组件中通过受控方式维护输入框中的数据
    3. 在组件中监听keyUp方法 判断当前是否点击的是回车键 如果是 调用mobx的方法进行新增

    src/store/taskStore.js

    // 新增
    addTask(task) {
      this.list.push(task)
    }
    
    • 1
    • 2
    • 3
    • 4

    src/Todo/index.js

    // 新增用户输入,受控方式维护输入框数据
    const [taskValue, setTaskValue] = useState('')
    function insertTask(e) {
      if (e.keyCode !== 13) return
      if (e.target.value.trim() === '') {
        alert('输入的内容不能为空')
        return
      }
      taskStore.addTask(
        {
          id: nanoid(),
          name: taskValue,
          isDone: false
        }
      )
      setTaskValue('')
      // e.target.value = ''
    }
    ...
    {/* 新增输入框 */}
    <input 
    	className="new-todo" autoFocus 
    	autoComplete="off" 
    	placeholder="What needs to be done?" 
    	value={taskValue} 
    	onChange={(e) => setTaskValue(e.target.value)} 
    	onKeyUp={(e) => { insertTask(e) }} />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    统计计数功能

    实现思路和步骤:

    1. 在mobx中编写已完成的数量的计算属性的逻辑
    2. 在组件中调用渲染

    src/store/taskStore.js

    // 已完成的数量的计算属性
    get isFinishedLength() {
      return this.list.filter(item => item.isDone).length
    }
    
    • 1
    • 2
    • 3
    • 4

    src/Todo/index.js

    <footer className='footer'>
      <span className='todo-count'>
        任务总数:{taskStore.list.length} 已完成:{taskStore.isFinishedLength}
    	</span>
    </footer>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    今天的分享就到这里啦✨ \textcolor{red}{今天的分享就到这里啦✨} 今天的分享就到这里啦

    原创不易,还希望各位大佬支持一下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下

    🤞 点赞,你的认可是我创作的动力! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!

    ⭐️ 收藏,你的青睐是我努力的方向! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!

    ✏️ 评论,你的意见是我进步的财富! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!

  • 相关阅读:
    哈希表题目:唯一摩尔斯密码词
    pjsip-2.9点对点时解决注册慢问题
    马上2023了,云原生架构还不懂?阿里云原生架构笔记带你完全拿下
    (附源码)springboot掌上博客系统 毕业设计063131
    JavaWeb基础(一)——Tomcat介绍
    uni-app,安卓,微信小程序,H5,代码模块判断使用
    一个瞬间让你的代码量暴增的脚本
    华为机试题解析020:数据分类处理(python)
    框架&Mybatis的基础了解
    VRRP基础
  • 原文地址:https://blog.csdn.net/xuxuii/article/details/126455133