您好,登錄后才能下訂單哦!
?
?
目錄
todolist項目:... 1
階段5,狀態(tài)的控制和改變:... 1
階段6,getter、setter:... 5
階段7,過濾數(shù)據(jù)方法調整:... 9
階段8,@computed的使用:... 13
階段9,完成狀態(tài),Symbol類型:... 14
階段10,axios,整合前后端:... 17
?
?
?
?
Redux和Mobx,社區(qū)提供的狀態(tài)管理庫;
Redux,代碼優(yōu)秀,使用嚴格的函數(shù)式編程思想,學習曲線陡峭,小項目使用的優(yōu)勢不明顯;
?
Mobx,優(yōu)秀穩(wěn)定的庫,簡單方便(內部實現(xiàn)復雜),適合中小項目使用,使用面向對象的方式,易學習和接受,現(xiàn)使用非常廣泛;
https://mobx.js.org/
http://cn.mobx.js.org/
mobx實現(xiàn)了觀察者模式(訂閱+廣播模式),觀察者觀察某個目標,obserable目標對象發(fā)生了變化,會通知自己內部注冊了的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(<TodoApp service={service}/>, document.getElementById('root'));
?
./src/service/service.js
解決復選框改變,列表不刷新問題:
1、手動修改todos,如下例,相當于change過;
2、用一常量,如@observable changed=false(或changed=時間戳+隨機數(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?? //觀察目標
??? 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控制狀態(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 (
??????????? <div>
??????????????? <Create onCreate={this.handleCreate.bind(this)}/>
??????????????? <Filter onChange={this.handleFilterChange.bind(this)}/>
??????????????? <br />
??????????????? {/* {this.service.todos.map(
??????????????????? item => <Todo todo={item} key={item.key} onChange={this.handleCheckedChange.bind(this)}/>)
??????????????? } */}
??????????????? {/* {
??????????????????? [...this.service.todos.values()].map(
??????????????????????? item => <Todo key={item.key} todo={item} onChange={this.handleCheckedChange.bind(this)} />
??????????????????? )
??????????????? } */}
??????????????? {
??????????????????? [...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 => <Todo key={item.key} todo={item} onChange={this.handleCheckedChange.bind(this)} />
??????????????????? )
??????????????? }
??????????? </div>
??????? );
??? }
}
?
./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 (
??????????? <div>
??????????????? <Create onCreate={this.handleCreate.bind(this)}/>
??????????????? <Filter onChange={this.handleFilterChange.bind(this)}/>
??????????????? <br />
??????????????? {/* {this.service.todos.map(
??????????????????? item => <Todo todo={item} key={item.key} onChange={this.handleCheckedChange.bind(this)}/>)
??????????????? } */}
??????????????? {/* {
??????????????????? [...this.service.todos.values()].map(
??????????????????????? item => <Todo key={item.key} todo={item} onChange={this.handleCheckedChange.bind(this)} />
??????????????????? )
??????????????? } */}
??????????????? {
??????????????????? [...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 => <Todo key={item.key} todo={item} onChange={this.handleCheckedChange.bind(this)} />
??????????????????? )
??????????????? }
??????????? </div>
??????? );
??? }
}
?
?
?
將過濾數(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?? //添加觀察目標對象
??? 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 (
??????????? <div>
??????????????? <Create onCreate={this.handleCreate.bind(this)}/>
??????????????? <Filter onChange={this.handleFilterChange.bind(this)}/>
??????????????? <br />
??????????????? {/* {this.service.todos.map(
??????????????????? item => <Todo todo={item} key={item.key} onChange={this.handleCheckedChange.bind(this)}/>)
??????????????? } */}
??????????????? {/* {
??????????????????? [...this.service.todos.values()].map(
??????????????????????? item => <Todo key={item.key} todo={item} onChange={this.handleCheckedChange.bind(this)} />
??????????????????? )
??????????????? } */}
??????????????? {
??????????????????? this.props.service.todos.map(
??????????????????????? item => <Todo key={item.key} todo={item} onChange={this.handleCheckedChange.bind(this)} />
??????????????????? )
??????????????? }
??????????? </div>
??????? );
??? }
}
?
?
?
mobx提供了@computed裝飾器,可用在任意類的屬性的getter上,它所依賴的值發(fā)生了變化就重新計算,否則直接返回上次計算的結果;
使用@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關鍵字,生成的不是對象,直接用函數(shù)調用方式使用;
Symbol每次返回一個獨一無二的值,即便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'),這樣相當于重新調用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;
??????????? store.set(key, todo);
??????? }
?
??????? let temp = this._todos;
??????? this._todos = {};?? //this.todos = () => {}
??????? this._todos = temp;
??? }
?
??? setTodoFilter(value) {
??????? // this.filter = value;
??????? this.filter = TodoService.TODOSTATES[value];
??? }
}
注:
./src/component/Filter.js
<Select style={{ width: 120 }} defaultValue="uncompleted" onChange={value => props.onChange(value)}>
antd在defaultValue={TodoService.TODOSTATE.uncompleted},不支持傳遞類.屬性這種,只能用字符串;
?
?
?
axios是一個異步HTTP庫,可用在瀏覽器或nodejs中;
?
例:
axios.get('/user?ID=12345')
? .then(function (response) {?? //返回200 OK的處理,response是返回的數(shù)據(jù)(區(qū)別于服務器的響應),具體看MIME類型,可以是picture、下載內容等
??? console.log(response);
? })
? .catch(function (error) {?? //異常的處理
??? console.log(error);
? });
?
注:
前端要操作DB,通過ajax或jquery(早期用)-->web服務器;
url + method --> restful;
post?? #add
put?? #modify
?
store.set(todo.key, todo)?? #當前是存儲在瀏覽器本地的Local Storage,實際是要存儲在數(shù)據(jù)庫上,這塊需改造
?
例:
webpack.config.dev.js?? #開發(fā)的win主機上更改
??? devServer: {
??????? compress: true,
??????? port: 3000,
??????? publicPath: '/assets/',
??????? hot: true,
??????? inline: true,
??????? historyApiFallback: true,
??????? stats: {
??????????? chunks: false
??????? },
??????? proxy: {
??????????? '/api': {
??????????????? target: 'http://192.168.23.134:80',?? //nginx主機配置
??????????????? changeOrigin: true
??????????? }
??????? }
??? }
$ npm run build?? #在項目根下打包
?
]# pwd?? #nginx主機上操作
/ane/packages
]# tar xf tengine-1.2.3.tar.gz
]# cd tengine-1.2.3/
]# yum -y install gcc openssl-devel pcre-devel
]# ./configure
]# make && make install
]# cd /usr/local/nginx/
]# vim conf/nginx.conf
??? server {
??????? listen?????? 80;
??????? server_name? localhost;
?
??????? #charset koi8-r;
?
??????? #access_log? logs/host.access.log? main;
??????? location /api/ {
??????????? proxy_pass http://192.168.7.144:8080;?? #win主機上運行的py開發(fā)的后臺app
??????? }
?
??????? location / {
??????????? root?? html;
??????????? index? index.html index.htm;
??????? }
]# tree ./?? #將打好包的index.html和app-56350ea8.js放到nignx上,app-*.js要放到assets/下
./
├── 50x.html
├── assets
│?? └── app-56350ea8.js
└── index.html
]# sbin/nginx?? #sbin/nginx -s reload,動態(tài)加載配置
]# netstat -tnulp | grep nginx
tcp??????? 0????? 0 0.0.0.0:80????????????? 0.0.0.0:*?????????????? LISTEN????? 2280/nginx: master?
?
http://192.168.23.134/
?
注:
nginx配置中先注釋location /api/ {……}這段,在create待辦事宜時報404;
nginx配置中有location /api/ {……}這段,在create待辦事宜時報502,因為后端還沒開啟py開發(fā)的后臺app;
?
?
win主機的pycharm中運行:
from aiohttp import web, log
import json
import logging
?
async def indexhandle(request: web.Request):
??? return web.Response(text='welcome to pyserver', status=200)
?
async def handle(request: web.Request):
??? print(request.match_info)
??? print(request.query_string)
??? return web.Response(text=request.match_info.get('id', '0000'), status=200)
?
async def todopost(request: web.Request):?? #協(xié)程函數(shù)
??? print(request.method)
??? print(request.match_info)
??? print(request.query_string)
??? print(request.json())
??? js = await request.json()?? #協(xié)程中用,同yield from
??? print(js, type(js))
??? text = dict(await request.post())
??? print(text, type(text))
??? js.update(text)
??? res = json.dumps(js)
??? print(res)
??? return web.Response(text=res, status=201)?? #201狀態(tài)碼表示Created
?
?
app = web.Application()
app.router.add_get('/', indexhandle)
app.router.add_get('/{id}', handle)
app.router.add_post('/api/todo', todopost)
?
app.logger.setLevel(level=logging.NOTSET)
web.run_app(app, host='0.0.0.0', port=8080)
輸出:
======== Running on http://0.0.0.0:8080 ========
(Press CTRL+C to quit)
POST
<MatchInfo {}: <ResourceRoute [POST] <PlainResource? /api/todo> -> <function todopost at 0x0000000003997A60>>
?
<coroutine object BaseRequest.json at 0x0000000003970F68>
{'completed': False, 'key': 'todo::1543038271618', 'title': 'test'} <class 'dict'>
{} <class 'dict'>
{"completed": false, "key": "todo::1543038271618", "title": "test"}
?
http://192.168.23.134
?
?
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。