74react_todolist2

 

惠民ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:028-86922220(备注:SSL证书合作)期待与您的合作!

 

目录

todolist项目:...1

阶段5,状态的控制和改变:...1

阶段6,getter、setter:...5

阶段7,过滤数据方法调整:...9

阶段8,@computed的使用:...13

阶段9,完成状态,Symbol类型:...14

阶段10,axios,整合前后端:...17

 

 

 

todolist项目:

 

阶段5,状态的控制和改变:

Redux和Mobx,社区提供的状态管理库;

Redux,代码优秀,使用严格的函数式编程思想,学习曲线陡峭,小项目使用的优势不明显;

 

Mobx,优秀稳定的库,简单方便(内部实现复杂),适合中小项目使用,使用面向对象的方式,易学习和接受,现使用非常广泛;

https://mobx.js.org/

http://cn.mobx.js.org/

mobx实现了观察者模式(订阅+广播模式),观察者观察某个目标,obserable目标对象发生了变化,会通知自己内部注册了的observer观察者;

 

 

./src/index.js

import React from 'react';

import ReactDom from 'react-dom';

 

import TodoApp from './component/TodoApp';

 

import TodoService from './service/service';

 

const service =new TodoService();   //service实例通过props属性传递到组件中

ReactDom.render(,document.getElementById('root'));

 

./src/service/service.js

解决复选框改变,列表不刷新问题:

1、手动修改todos,如下例,相当于change过;

2、用一常量,如@observable changed=false(或changed=时间戳+随机数),但这个变量要在render()中用到,哪怕写{this.props.service.changed}都行反正要用到,否则不会刷新;

import store from 'store';

import {observable}from 'mobx';

 

export default class TodoService {

   constructor() {

       // super();

       this.load();

    }

 

   load() {

       store.each((value,key)=> {

           if (key.startsWith(TodoService.NAMESPACE))

               // this.todos.push(value);

               this.todos.set(key,value);

        });

       console.log(this.todos);

    }

   

   static NAMESPACE ='todo::';

 

   // todos = [];

    @observable   //观察目标

   todos =new Map();

 

   create(title) {

       // console.log('service');

       const todo = {

           key: TodoService.NAMESPACE + (new Date()).valueOf(),

           title: title,

           completed: false

        };

 

       // this.todos.push(todo);

       this.todos.set(todo.key,todo);

       store.set(todo.key,todo);

       return todo;

    }

 

   setTodoState(key,checked) {

       let todo =this.todos.get(key);

       if (todo) {

           todo.completed =checked;

           store.set(key,todo);

        }

       let temp =this.todos;   //改变观察目标,解决Checkbox复选框改变列表不刷新问题

       this.todos = {};  //同this.todos = () => {}

       this.todos =temp;

    }

}

 

./src/component/TodoApp.js

this.props.service.create(event.target.value),index.js已定义,此处用props属性访问;

之前的this.state=({todos: this.service.todos})注释,当前使用mobx控制状态;

import React from 'react';

import Create from './Create';

// import TodoService from '../service/service';

import Todo from './Todo';

import Filter from './Filter';

import {observer}from 'mobx-react';   //注意此处是mobx-react

 

@observer

export default class TodoApp extends React.Component {

   constructor(props) {

       super(props);

       // this.service = new TodoService();

       // this.state = ({todos: this.service.todos, filter: 'uncompleted'});

       this.state = ({filter: 'uncompleted'});

    }

 

   // handleCreate(...args) {

   //     console.log('Root handlerCreate');

   //     console.log(this);

   //     console.log('args is ', args);

   // }

   handleCreate(event) {

       // console.log('Root handleCreate');

       // console.log(this);

       // console.log('event is ', event, event.target, event.target.value);

       this.props.service.create(event.target.value);

       // this.setState({todos: this.service.todos});

    }

 

   handleCheckedChange(key,checked) {  //handleCheckedChange(event),event.target.checked=false|true

       console.log('handleCheckedChange',key,checked);

       this.props.service.setTodoState(key,checked);

       // this.setState({todos: this.service.todos});

    }

 

   handleFilterChange(value) {

       // console.log('~~~~~~~', args);

       // console.log(this);

       console.log(value);

       this.setState({filter: value});;

    }

 

   render() {

       return (

           

               

               

               

               {/* {this.service.todos.map(

                    item => )

                } */}

               {/* {

                    [...this.service.todos.values()].map(

                        item =>

                    )

                } */}

               {

                    [...this.props.service.todos.values()].filter(

                       item => {

                           let fs =this.state.filter;

                           if(fs ==='all') {

                               return true;

                            }else if(fs ==='completed') {

                               // if(item.completed === true)

                               //     return true;

                               // else

                               //     return false;

                               return item.completed ===true;

                            }else if(fs ==='uncompleted') {

                                // if(item.completed === false)

                               //     return true;

                               // else

                               //     return false;

                               return item.completed ===false;

                            }

                        }

                    ).map(

                       item =>

                    )

               }

           

        );

    }

}

 

./src/component/{Create.js,Todo.js,Filter.js}不动;

 

 

 

阶段6,getter、setter:

类似py的property装饰器;

 

./src/service/service.js

import store from 'store';

import {observable}from 'mobx';

 

export default class TodoService {

   constructor() {

       // super();

       this.load();

    }

 

   load() {

       store.each((value,key)=> {

           if (key.startsWith(TodoService.NAMESPACE))

               // this.todos.push(value);

               this._todos.set(key,value);

        });

       // console.log(this.todos);

    }

   

   static NAMESPACE ='todo::';

 

   // todos = [];

    @observable

   _todos =new Map();

 

   get todos() {   //getter

       return this._todos;

    }

   

   create(title) {

       // console.log('service');

       const todo = {

           key: TodoService.NAMESPACE + (new Date()).valueOf(),

           title: title,

           completed: false

        };

 

       // this.todos.push(todo);

       this._todos.set(todo.key,todo);

       store.set(todo.key,todo);

 

       let temp =this._todos;   //类似setter;这三句放到此处,解决新创建的待办事宜的刷新问题

       this._todos = {};

       this._todos =temp;

 

       return todo;

    }

 

   setTodoState(key,checked) {

       let todo =this._todos.get(key);

       if (todo) {

           todo.completed =checked;

           store.set(key,todo);

        }

 

       let temp =this._todos;   //setter

       this._todos = {};  //this.todos = () => {}

       this._todos =temp;

    }

}

 

./src/component/TodoApp.js

import React from 'react';

import Create from './Create';

// import TodoService from '../service/service';

import Todo from './Todo';

import Filter from './Filter';

import {observer}from 'mobx-react';

 

@observer

export default class TodoApp extends React.Component {

   constructor(props) {

       super(props);

       // this.service = new TodoService();

       // this.state = ({todos: this.service.todos, filter: 'uncompleted'});

       this.state = ({filter: 'uncompleted'});

    }

 

   // handleCreate(...args) {

   //     console.log('Root handlerCreate');

   //     console.log(this);

   //     console.log('args is ', args);

   // }

   handleCreate(event) {

       // console.log('Root handleCreate');

       // console.log(this);

       // console.log('event is ', event, event.target, event.target.value);

       this.props.service.create(event.target.value);

       // this.setState({todos: this.service.todos});

    }

 

   handleCheckedChange(key,checked) {  //handleCheckedChange(event),event.target.checked=false|true

       // console.log('handleCheckedChange', key, checked);

       this.props.service.setTodoState(key,checked);

       // this.setState({todos: this.service.todos});

    }

 

   handleFilterChange(value) {

       // console.log('~~~~~~~', args);

       // console.log(this);

       // console.log(value);

       this.setState({filter: value});;

    }

 

   render() {

       return (

           

               

               

               

               {/* {this.service.todos.map(

                    item => )

                } */}

               {/* {

                    [...this.service.todos.values()].map(

                        item =>

                    )

                } */}

               {

                    [...this.props.service.todos.values()].filter(

                       item => {

                           let fs =this.state.filter;

                           if(fs ==='all') {

                               return true;

                            }else if(fs ==='completed') {

                               // if(item.completed === true)

                               //     return true;

                               // else

                               //     return false;

                               return item.completed ===true;

                            }else if(fs ==='uncompleted') {

                               // if(item.completed === false)

                               //     return true;

                               // else

                               //     return false;

                                return item.completed ===false;

                            }

                        }

                    )

                    .map(

                       item =>

                    )

               }

           

        );

    }

}

 

 

 

阶段7,过滤数据方法调整:

将过滤数据的filter,移到service.js中;

 

./src/service/service.js

import store from 'store';

import {observable}from 'mobx';

 

export default class TodoService {

   constructor() {

       // super();

       this.load();

    }

 

   load() {

       store.each((value,key)=> {

           if (key.startsWith(TodoService.NAMESPACE))

               // this.todos.push(value);

               this._todos.set(key,value);

        });

       // console.log(this.todos);

    }

   

   static NAMESPACE ='todo::';

 

   // todos = [];

    @observable

   _todos =new Map();

    @observable   //添加观察目标对象

   filter ='uncompleted';

 

   get todos() {   //getter,_todos变量

       // return this._todos;

       return [...this._todos.values()].filter(

           item => {

               let fs =this.filter;

               if(fs ==='all') {

                   return true;

                }else if(fs ==='completed') {

                   // if(item.completed === true)

                   //     return true;

                   // else

                   //     return false;

                   return item.completed ===true;

                }else if(fs ==='uncompleted') {

                   // if(item.completed === false)

                   //     return true;

                   // else

                   //     return false;

                   return item.completed ===false;

                }

            }

        );

    }

   

   create(title) {

       // console.log('service');

       const todo = {

           key: TodoService.NAMESPACE + (new Date()).valueOf(),

           title: title,

           completed: false

        };

 

       // this.todos.push(todo);

       this._todos.set(todo.key,todo);

       store.set(todo.key,todo);

 

       let temp =this._todos;

       this._todos = {};

       this._todos =temp;

 

       return todo;

    }

 

   setTodoState(key,checked) {

       let todo =this._todos.get(key);

       if (todo) {

           todo.completed =checked;

           store.set(key,todo);

        }

 

       let temp =this._todos;

       this._todos = {};  //this.todos = () => {}

       this._todos =temp;

    }

 

   setTodoFilter(value) {

       this.filter =value;

    }

}

 

./src/component/TodoApp.js

import React from 'react';

import Create from './Create';

// import TodoService from '../service/service';

import Todo from './Todo';

import Filter from './Filter';

import {observer}from 'mobx-react';

 

@observer

export default class TodoApp extends React.Component {

   constructor(props) {

       super(props);

       // this.service = new TodoService();

       // this.state = ({todos: this.service.todos, filter: 'uncompleted'});

       // this.state = ({filter: 'uncompleted'});   //filter使用mobx管理

    }

 

   // handleCreate(...args) {

   //     console.log('Root handlerCreate');

   //     console.log(this);

   //     console.log('args is ', args);

   // }

   handleCreate(event) {

       // console.log('Root handleCreate');

       // console.log(this);

       // console.log('event is ', event, event.target, event.target.value);

       this.props.service.create(event.target.value);

       // this.setState({todos: this.service.todos});

    }

 

   handleCheckedChange(key,checked) {  //handleCheckedChange(event),event.target.checked=false|true

       // console.log('handleCheckedChange', key, checked);

       this.props.service.setTodoState(key,checked);

       // this.setState({todos: this.service.todos});

    }

 

   handleFilterChange(value) {

       // console.log('~~~~~~~', args);

       // console.log(this);

       // console.log(value);

        // this.setState({filter: value});;

       this.props.service.setTodoFilter(value);

    }

 

   render() {

       return (

           

               

               

               

               {/* {this.service.todos.map(

                    item => )

                } */}

               {/* {

                    [...this.service.todos.values()].map(

                        item =>

                    )

                } */}

               {

                   this.props.service.todos.map(

                       item =>

                    )

               }

           

        );

    }

}

 

 

 

阶段8,@computed的使用:

mobx提供了@computed装饰器,可用在任意类的属性的getter上,它所依赖的值发生了变化就重新计算,否则直接返回上次计算的结果;

使用@computed装饰get todos();

 

./src/service/service.js

import {observable,computed}from 'mobx';

export default class TodoService {

……

    @computed   //程序员感知不到变化,观察对象_todos和filter任意一个变化都会重新计算

   get todos() {

       // return this._todos;

       return [...this._todos.values()].filter(

           item => {

               let fs =this.filter;

               if(fs ==='all') {

                   return true;

                }else if(fs ==='completed') {

                   // if(item.completed === true)

                   //     return true;

                   // else

                   //     return false;

                   return item.completed ===true;

                }else if(fs ==='uncompleted') {

                   // if(item.completed === false)

                   //     return true;

                   // else

                   //     return false;

                   return item.completed ===false;

                }

            }

        );

    }

……

}

 

 

 

阶段9,完成状态,Symbol类型:

Symbol类型,是JS中的基本类型;

是ES6新增的主数据类型,是一种特殊的、不可变的数据类型;

Symbol([description]),description是可选的字符串;

不可使用new关键字,生成的不是对象,直接用函数调用方式使用;

Symbol每次返回一个独一无二的值,即便2次的描述一样,描述只是为了使人阅读方便,便于区分不同的Symbol值;

 

例:

let sym0 =Symbol();

let sym1 =Symbol();

let sym2 =Symbol('symbol2');

let sym3 =Symbol('symbol2');

 

console.log(sym0 ===sym1);

console.log(sym1 ===sym2);

输出:

false

false

 

 

./src/service/service.js

import store from 'store';

import {observable,computed}from 'mobx';

 

const ALL =Symbol('all');

const COMPLETED =Symbol('completed');

const UNCOMPLETED =Symbol('uncompleted');

 

export default class TodoService {

   constructor() {

       // super();

       this.load();

    }

 

   load() {

       store.each((value,key)=> {

           if (key.startsWith(TodoService.NAMESPACE))

               // this.todos.push(value);

               this._todos.set(key,value);

        });

       // console.log(this.todos);

    }

   

   static NAMESPACE ='todo::';

   static TODOSTATES = {

       // all: 'all',

       all: ALL,

       // completed: 'completed',

       completed: COMPLETED,

       // uncompleted: 'uncompleted'

       uncompleted: UNCOMPLETED

    }

 

   // todos = [];

    @observable

   _todos =new Map();

    @observable

   // filter = 'uncompleted';

   filter =TodoService.TODOSTATES.uncompleted;

 

    @computed

   get todos() {

       // return this._todos;

       return [...this._todos.values()].filter(

           item => {

               let fs =this.filter;

               // if(fs === 'all') {

               if(fs ===TodoService.TODOSTATES.all) {   //只能用类.属性这种方式,不可以fs === Symbol('all'),这样相当于重新调用Symbol()是个新值;===常用,严格相等;==要做隐式转换,不用

                   return true;

               // } else if(fs === 'completed') {

                }else if(fs ===TodoService.TODOSTATES.completed) {

                   // if(item.completed === true)

                   //     return true;

                   // else

                   //     return false;

                   return item.completed ===true;

               // } else if(fs === 'uncompleted') {

                }else if(fs ===TodoService.TODOSTATES.uncompleted) {

                   // if(item.completed === false)

                   //     return true;

                   // else

                   //     return false;

                   return item.completed ===false;

                }

            }

        );

    }

   

   create(title) {

       // console.log('service');

       const todo = {

           key: TodoService.NAMESPACE + (new Date()).valueOf(),

           title: title,

           completed: false

        };

 

       // this.todos.push(todo);

       this._todos.set(todo.key,todo);

       store.set(todo.key,todo);

 

       let temp =this._todos;

       this._todos = {};

       this._todos =temp;

 

       return todo;

    }

 

   setTodoState(key,checked) {

       let todo =this._todos.get(key);

       if (todo) {

           todo.completed =checked;


当前题目:74react_todolist2
浏览路径:http://ybzwz.com/article/jgopgo.html