mobx-TodoList-6版本
写react demo不写版本就是不讲武德。(把react去掉)
版本:
"react": "^17.0.2",
"mobx": "^6.3.3",
"mobx-react": "^7.2.0",
"@babel/core": "7.12.3",
"@babel/plugin-proposal-decorators": "^7.15.4",
安装:
npm install mobx mobx-react -S
git init && git add . && git commit -m 'init' // 使用eject之前本地仓库必须有提交记录。记得创建一下.gitignore文件。
npm run eject
npm @babel/plugin-proposal-decorators -S // 修饰器 这东西一直在变,所以只能做参考,有问题度娘把。
package.js配置
...
"babel": {
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
]
],
"presets": [
"react-app"
]
},
...
不会更新的基本数据模型
class TodoStore {
todos = []
get completedTodosCount() {
return this.todos.filter(todo => todo.completed === true).length
}
report() {
if (this.todos.length === 0)
return "<无>";
const nextTodo = this.todos.find(todo => todo.completed === false);
// console.log(this.todos)
// console.log(nextTodo)
return `下一个待办:"${nextTodo ? nextTodo.task : "<无>"}"。 ` +
`进度:${this.completedTodosCount}/${this.todos.length}`;
}
addTodo(task) {
this.todos.push({
task: task,
completed: false,
assignee: null,
})
}
}
const todoStore = new TodoStore()
todoStore.addTodo("阅读 MobX 教程");
console.log(todoStore.report());
todoStore.addTodo("试用 MobX");
console.log(todoStore.report());
todoStore.todos[0].completed = true;
console.log(todoStore.report());
todoStore.todos[1].task = "在自己的项目中试用 MobX";
console.log(todoStore.report());
todoStore.todos[0].task = "理解 MobX 教程";
console.log(todoStore.report());
加入了mobx的observable的例子
import {computed, action, autorun, makeObservable, observable } from "mobx"
class ObservableTodoStore {
todos = []
pendindRequests = 0
constructor() {
makeObservable(this, {
todos: observable,
pendingRequests: observable, // 是否请求中...,后面模拟异步请求使用。
completedTodosCount: computed,
report: computed,
addTodo: action,
})
autorun(() => console.log(this.report))
}
get completedTodosCount() { // 自动计算完成数
return this.todos.filter( todo => todo.completed === true).length
}
get report() {
if (this.todos.length === 0)
return "<无>";
const nextTodo = this.todos.find(todo => todo.completed === false);
return `下一个待办:"${nextTodo ? nextTodo.task : "<无>"}"。 ` +
`进度:${this.completedTodosCount}/${this.todos.length}`;
}
addTodo(task) {
this.todos.push({
task,
completed: false,
assignee: null
})
}
}
const observableTodoStore = new ObservableTodoStore()
observableTodoStore.addTodo("阅读 MobX 教程1");
observableTodoStore.addTodo("试用 MobX2");
observableTodoStore.todos[0].completed = true;
observableTodoStore.todos[1].task = "在自己的项目中试用 MobX3";
observableTodoStore.todos[0].task = "理解 MobX 教程4";
// 在index.js里面import 引入执行即可。
完整版
import {computed, action, autorun, makeObservable, observable } from "mobx"
class ObservableTodoStore {
todos = []
pendingRequests = 0
constructor() {
makeObservable(this, {
todos: observable,
pendingRequests: observable,
completedTodosCount: computed,
report: computed,
addTodo: action,
})
autorun(() => console.log(this.report))
}
get completedTodosCount() {
return this.todos.filter( todo => todo.completed === true).length
}
get report() {
if (this.todos.length === 0)
return "<无>";
const nextTodo = this.todos.find(todo => todo.completed === false);
return `下一个待办:"${nextTodo ? nextTodo.task : "<无>"}"。 ` +
`进度:${this.completedTodosCount}/${this.todos.length}`;
}
addTodo(task) {
this.todos.push({
task,
completed: false,
assignee: null
})
}
}
let store = new ObservableTodoStore()
// 里面使用了proxy,所以在没有实例之前不能使用store.todos[0].task='xxx'这样的写法
store.addTodo('完成mobx-react-todolist-demo') // 同下效果。
store.todos.push({
task:'代办事项',
completed: false,
assignee: null
})
console.dir(store.todos)
// 另外加入任务者名称,使用observable,新增加的数组对象也会被加入可观察者队列并被追踪。
const peopleStore = observable([
{
name: 'Michel',
},
{
name: 'hjj',
},
])
// 预先载入数据作为例子。
store.todos[0].completed = true
store.todos[0].assignee = peopleStore[0]
store.todos[1].assignee = peopleStore[1]
export default store
TodoListView.js
import { action, observable } from 'mobx'
import {
observer
} from 'mobx-react'
const TodoList = observer(({store}) => {
const onNewTodo = () => {
let tack = prompt('输入新的代办:', '请来杯咖啡')
if(tack) store.addTodo(tack)
}
const syncNewTodo = () => {
store.pendingRequests++
setTimeout(action( () => {
store.addTodo('随机代办' + Math.random())
store.pendingRequests--
}), 2000)
}
return (
<div>
{store.report}
<ul>
{store.todos.map(
(todo, idx) => <TodoView todo={todo} key={idx} />
)}
</ul>
{store.pendingRequests > 0 ? <marquee>正在加载...</marquee>: null}
<br />
<button onClick={onNewTodo}>新代办</button>
<button onClick={syncNewTodo}>异步添加新代办</button>
<small>(双击代办进行编辑)</small>
{/* <RenderCounter /> */}
</div>
)
})
const TodoView = observer(({todo}) => {
const onToggleCompleted = () => {
todo.completed = !todo.completed
}
const onSetValue = (e) => {
todo.assignee = {name: e.target.value}
}
const onRename = () => {
todo.task = prompt('任务名称', todo.task) || todo.task
}
return (
<li onDoubleClick={onRename}>
<input type='checkbox' checked={todo.completed} onChange={onToggleCompleted} />
{todo.task} --
{todo.assignee ? <small>{todo.assignee.name}</small>: null}
<br /> 修改任务者:<input onKeyUp={onSetValue} />
{/* <RenderCounter /> */}
</li>
)
})
export default TodoList
完成了store.js和view.js,在index.js中引入即可
import React from 'react';
import ReactDOM from 'react-dom';
// import './index.css';
// import App from './App';
import reportWebVitals from './reportWebVitals';
import TodoList from './TodoList'
import observableTodoStore from './store'
ReactDOM.render(
<React.StrictMode>
<TodoList store={observableTodoStore}></TodoList>
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();