!
也想出现在这里? 联系我们
广告区块

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

前言

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

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


Todos综合案例

效果

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

Mobx和React的职责划分

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

列表渲染

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)
【Mobx和React的职责划分】Todos综合案例分析(附源码)

单选实现

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

  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
【Mobx和React的职责划分】Todos综合案例分析(附源码)

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. 实现数据驱动权限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)
}

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. 在mobx中定义好删除数据的方法

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

src/store/taskStore.js

// 删除操作
delTask(id) {
  this.list = this.list.filter(item => item.id !== id)
}

src/Todo/index.js

// 删除
function delTask(id) {
  taskStore.delTask(id)
}
...
{/* 删除按钮 */}
button className="destroy" onClick={() => { delTask(item.id) }}>/button>

回车新增功能

实现思路和步骤:

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

src/store/taskStore.js

// 新增
addTask(task) {
  this.list.push(task)
}

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) }} />
【Mobx和React的职责划分】Todos综合案例分析(附源码)

统计计数功能

实现思路和步骤:

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

src/store/taskStore.js

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

src/Todo/index.js

footer className='footer'>
  span className='todo-count'>
    任务总数:{taskStore.list.length} 已完成:{taskStore.isFinishedLength}
	/span>
/footer>

今天的分享就到这里啦✨

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

今天的分享就到这里啦

原创不易,还希望各位大佬支持一下

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

原创不易,还希望各位大佬支持一下

?

点赞,你的认可是我创作的动力!

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

点赞,你的认可是我创作的动力!

⭐️

收藏,你的青睐是我努力的方向!

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

收藏,你的青睐是我努力的方向!

✏️

评论,你的意见是我进步的财富!

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

评论,你的意见是我进步的财富!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xuxuii/article/details/126455133
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
有新私信 私信列表
搜索