?
惠民ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!
?
目錄
todolist項目:...1
階段5,狀態(tài)的控制和改變:...1
階段6,getter、setter:...5
階段7,過濾數(shù)據(jù)方法調(diào)整:...9
階段8,@computed的使用:...13
階段9,完成狀態(tài),Symbol類型:...14
階段10,axios,整合前后端:...17
?
?
?
?
Redux和Mobx,社區(qū)提供的狀態(tài)管理庫;
Redux,代碼優(yōu)秀,使用嚴(yán)格的函數(shù)式編程思想,學(xué)習(xí)曲線陡峭,小項目使用的優(yōu)勢不明顯;
?
Mobx,優(yōu)秀穩(wěn)定的庫,簡單方便(內(nèi)部實(shí)現(xiàn)復(fù)雜),適合中小項目使用,使用面向?qū)ο蟮姆绞?,易學(xué)習(xí)和接受,現(xiàn)使用非常廣泛;
https://mobx.js.org/
http://cn.mobx.js.org/
mobx實(shí)現(xiàn)了觀察者模式(訂閱+廣播模式),觀察者觀察某個目標(biāo),obserable目標(biāo)對象發(fā)生了變化,會通知自己內(nèi)部注冊了的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實(shí)例通過props屬性傳遞到組件中
ReactDom.render(
?
./src/service/service.js
解決復(fù)選框改變,列表不刷新問題:
1、手動修改todos,如下例,相當(dāng)于change過;
2、用一常量,如@observable changed=false(或changed=時間戳+隨機(jī)數(shù)),但這個變量要在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?? //觀察目標(biāo)
???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;?? //改變觀察目標(biāo),解決Checkbox復(fù)選框改變列表不刷新問題
???????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})注釋,當(dāng)前使用mobx控制狀態(tài);
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}不動;
?
?
?
類似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;這三句放到此處,解決新創(chuàng)建的待辦事宜的刷新問題
???????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 =>
??????????????????? )
???????????????}
???????????
??????? );
??? }
}
?
?
?
將過濾數(shù)據(jù)的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?? //添加觀察目標(biāo)對象
???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 =>
??????????????????? )
???????????????}
???????????
??????? );
??? }
}
?
?
?
mobx提供了@computed裝飾器,可用在任意類的屬性的getter上,它所依賴的值發(fā)生了變化就重新計算,否則直接返回上次計算的結(jié)果;
使用@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;
??????????????? }
??????????? }
??????? );
??? }
……
}
?
?
?
Symbol類型,是JS中的基本類型;
是ES6新增的主數(shù)據(jù)類型,是一種特殊的、不可變的數(shù)據(jù)類型;
Symbol([description]),description是可選的字符串;
不可使用new關(guān)鍵字,生成的不是對象,直接用函數(shù)調(diào)用方式使用;
Symbol每次返回一個獨(dú)一無二的值,即便2次的描述一樣,描述只是為了使人閱讀方便,便于區(qū)分不同的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'),這樣相當(dāng)于重新調(diào)用Symbol()是個新值;===常用,嚴(yán)格相等;==要做隱式轉(zhuǎn)換,不用
???????????????????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;