91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

react項目基本實踐

發布時間:2020-06-29 10:35:58 來源:網絡 閱讀:1107 作者:長跑者1號 欄目:web開發

一 localstorage和基本組件介紹

1 localstorage介紹

localstorage 是瀏覽器端持久化方案之一,HTML5標準增加的技術
localstorage 是為了存儲交互的數據,如json。
數據存儲就是鍵值在不同域名下的存儲
不同瀏覽器對單個域名下存儲數據的長度支持不同,有的最多支持2MB

如下

react項目基本實踐

其中sessionstorage是會話級別的存儲,及就是臨時存儲。
localstorage 支持的瀏覽器最多而sessionstorage支持的瀏覽器卻較少。
下面的indexedDB和web SQL 是和數據庫存儲有關,

indexedDB:
一個域一個datatable
key-value 檢索方式
建立在關系型數據庫上,具有索引表,游標,事務等概念。

2 store.js

store.js是一個兼容所有瀏覽器的localstorage包裝器,不需要借助cookie或者flash,store.js會根據瀏覽器自動選擇使用localstorage,globalstorage或者 userdata來實現本地存儲功能。


安裝

npm  i store  --save //此處是在部署包中添加 

react項目基本實踐

介紹和相關說明

https://github.com/marcuswestin/store.js/

測試代碼如下

var store = require('store') //導入模塊
store.set('user','test')  //設置key,value值
console.log(store.get('user'))  //獲取key,value值
store.remove('user') //移除key,及其和對應的value
console.log(store.get('user','aaaaa')) //查詢不存在時使用默認 
store.clearAll()  //清除所有 
store.set('test','test') // 設置 
store.each(function  (value,key)  {    //遍歷key和value,注意,此處是value,key 
    console.log(key,'====',value)
})

結果如下

react項目基本實踐

3 antd組件相關介紹

用戶提交數據,需要表單控件,而這種用戶提交的數據顯示就是view層需要完成的功能,對于react來說是一個空間,但這些控件需要用戶看到,為了美觀,引入了antd。


ant Design 螞蟻金服開源的reactUI庫

antd官網

https://ant.design/index-cn

官方文檔

https://ant.design/docs/react/introduce-cn

1 Input組件

使用一種較為簡單的組件Input來完成輸入功能

地址如下

https://ant.design/components/input-cn/

基礎代碼如下

import { Input } from 'antd';

ReactDOM.render(<Input placeholder="Basic usage" />);

輸入框屬性

addonAfter 帶標簽的 input,設置后置標簽 string|ReactNode
addonBefore 帶標簽的 input,設置前置標簽 string|ReactNode
placeholder="Basic usage" 占位詞
size="smail" 小輸入框,改為large就是大輸入框

2 Card 組件

顯示一個較為友好的界面

地址如下

https://ant.design/components/card-cn/

相關映射如下,最后面的style={{width:300}} 表示樣式,其是指寬度

react項目基本實踐

3 CheckBox多選框

相關處理可以使用checkbox組件來完成,選中和取消選中

https://ant.design/components/checkbox-cn/#header

基礎代碼如下

import { Checkbox } from 'antd';

function onChange(e) {
  console.log(`checked = ${e.target.checked}`);  //打印選擇結果 
}
//onChange 選中,取消時觸發回調函數.checked 表示是否選中,若選中,則為true,未選中,則為false 
ReactDOM.render(<Checkbox   onChange={onChange}>Checkbox</Checkbox>, mountNode);

4 柵格顯示

https://ant.design/components/grid-cn/

布局上,ant design 和 bootstrap很像,都使用一套柵格系統,使用24柵格,也就是每一個內部都切分成24份

import?React??from??'react';
import??{Checkbox,Card,Row,Col}???from??'antd';
import??'antd/lib/row/style';
import?'antd/lib/card/style';
import?'antd/lib/Col/style';

//一條待辦事宜
export??default??props?=>?(
????<Card??style={{width:600}}>
????????<Row>
????????????<Col?span="4"><Checkbox /></Col>
????????????<Col?span="20">{props.todo.title}</Col>
????????</Row>?
??????</Card>?
);

5 Select 對的篩選和顯示

過濾是指,過濾什么狀態的待辦事宜
應該有3種選擇:未完成,完成的和全部的,和后面的completed 參數結合使用。

使用select模塊來完成選擇框的使用,相關地址如下

https://ant.design/components/select-cn/
import { Select } from 'antd';

const { Option } = Select;

function onChange(value) {
  console.log(`selected ${value}`);
}

function onBlur() {
  console.log('blur');
}

function onFocus() {
  console.log('focus');
}

function onSearch(val) {
  console.log('search:', val);
}

ReactDOM.render(
  <Select
    showSearch
    style={{ width: 200 }}
    placeholder="Select a person"
    optionFilterProp="children"
    onChange={onChange}
    onFocus={onFocus}
    onBlur={onBlur}
    onSearch={onSearch}
    filterOption={(input, option) =>
      option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
    }
  >
    <Option value="jack">Jack</Option>
    <Option value="lucy">Lucy</Option>
    <Option value="tom">Tom</Option>
  </Select>,

4 Map 用于數據的持久化處理

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map

相關測試代碼如下

m=new Map();
m.set(1,'a');  //定義key和value 
m.set(2,'b');
m.set(3,'c');

console.log(m);  //查看結果 

let t=m.forEach((value,key)=> [key,value]);  // 此處無返回值 

console.log(t);  

t=[...m.values()].map(item => item+100);  // 對可迭代對象的解構,并進行處理,map 立即返回
console.log(t)

結果如下

react項目基本實踐

5 狀態管理Mobx

Redux 和 Mobx

上述項目中基本功能都實現了。但state的控制顯得有些麻煩。

社區提供了狀態管理庫,有Redux和Mobx

Redux 代碼優秀,使用嚴格的函數式編程思想,學習曲線陡峭,小項目使用的優勢不明顯
Mobx,穩定,使用簡單方便,適合中小型項目的使用,使用面向對象的方式學習,容易學習和接受,現在,使用也非常廣泛。


Mobx 官網

https://mobx.js.org/

中文網

https://cn.mobx.js.org/

Mobx實現了觀察者模式

觀察者模式
觀察者觀察某個目標,目標對象(Obserable)發生了變化,就會通知自己內部注冊的觀察者Observer

react項目基本實踐

觀察者模式,及就是一對多的廣播模式

首先,需要觀察者和被觀察者

目標對象,及被觀察者,obserable 指的是數據的源頭,被觀察者可以有多個,同時觀察這個變化。只要被觀察的對象有變化,則便會導致觀察者做出相應的操作,state和props變化是我們關心的,


@computed 的使用

mobx還提供了一個裝飾器@computed,可以使用在任意類上屬性的getter上使用,其所依賴的值發生了變化就會重新計算,否則直接返回到上次計算的結果。起到了緩存的作用,可直接用于filter的判斷上,通過傳入的值來進行相關匹配進而進行返回或計算。

6 異步處理和打包部署

異步處理axios
官網

http://www.axios-js.com/zh-cn/docs/

基礎代碼如下

// 為給定 ID 的 user 創建請求
axios.get('/user?ID=12345')
  .then(function (response) { //返回成功執行的代碼
    console.log(response);
  })
  .catch(function (error) {  //返回失敗執行的代碼  
    console.log(error);
  });

axios.post('/user', {  //下面的兩個表示key和value的值傳遞到服務器端
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

二 業務需求和基本代碼實現

1 需求分析

分層
視圖層,負責顯示數據,每一個react 組件一個js文件。

服務層,負責業務數據處理邏輯,命名為xxxService.js。

model層,負責數據,這里使用localstore。

注意:未特別說明,這些層的代碼都在項目跟目錄的src中

2 代碼實現

1 服務層實現

此處仍使用上一節項目包,相關介紹如下

https://blog.51cto.com/11233559/2443713


項目包如下
鏈接:https://pan.baidu.com/s/1C-ZY9rWU-8ZugE4EwVveWw
提取碼:744p

具體項目介紹。請查看上一節 react項目基礎

構建TodoService類,文件名為service.js,此目前放置在src的目錄下

react項目基本實踐

import  store  from  'store' 
export  default  class TodoService{
    static NAMESPACE="todo"  //定義存儲前綴 
    todos=[];  //定義存儲容器 
    // 創建todo  
    create(title) { //定義函數,用于處理創建和存儲數據
        const todo = {  //定義value類型 
        key: TodoService.NAMESPACE+(new Date()).valueOf(),    /*毫秒時間戳*/
        title :title,  //定義相關類型 
        completed: false //定義數據狀態
        }
        this.todos.push(todo);  //存儲至容器中
        //持久化處理
        store.set(todo.key,todo);
        return todo
    }
}

2 創建數據來源

title 從哪里來
從瀏覽器端,用戶提交,也就是視圖層提供的用戶提交的文本框,通過Card和 INput來處理數據的接受和啟動問題。


創建create.js 文件,其路徑暫時存放與src目錄下,此安裝包antd默認已經在包中存在,若未安裝,則需使用npm i antd進行安裝


使用這兩個組件組合,基礎測試代碼如下

import  React  from  'react';
import { Card,Input } from 'antd';
import  'antd/lib/card/style'  //導入相關樣式表 
import 'antd/lib/Input/style'
//缺省導出無狀態組件react 中 
export default props  => (
    <Card title="請輸入" style={{ width: 300 }}>
        <Input  />
    <p>測試代碼</p>
     </Card>
)

開放接口層代碼 index.js 相關代碼如下

import?React?from?'react';   
import?ReactDOM?from?'react-dom';
import Create  from  './create'  //引入模塊 

class??Root?extends??React.Component??{
    render(){
        return  (<div>
            hello world 
            <hr/>
            <Create />   //引入顯示
        </div>)
    }
}
ReactDOM.render(<Root/>,document.getElementById('root'));

結果如下

react項目基本實踐

輸入框處理,為了能讓用戶提交信息,我們需要是哦有那個接受回車鍵的事件觸發提交信息,鍵盤按下是一個事件,在Input中使用onPressEnter來收集鍵盤按下回車鍵的觸發指令。

react項目基本實踐

此處表明后面跟的是一個函數

修改如下
打印回車數據,其是通過event.target.value獲取到Input框中的數據的

import  React  from  'react';
import { Card,Input } from 'antd';
import  'antd/lib/card/style'  //導入相關樣式表 
import 'antd/lib/Input/style'
//缺省導出無狀態組件react 中 
export default props  => (
    <Card title="請輸入" style={{ width: 300 }}>
        <Input  onPressEnter={(event)  =>{console.log(event.target.value)}}/>  {/*此處使用event表示觸發的事件,其表示獲取到用戶數據*/}
    <p>測試代碼</p>
     </Card>
)

拿到用戶數據,應該調用todoservice的create,但不適合在create.js中進行調用,通過props 進行組件之間的數據共享。使用props
Root組件中創建一個handleCreate(title),用于處理Input中的數據傳輸到后臺,通過調用后臺的函數方法來完成。

index.js組件內容

import?React?from?'react';
import?ReactDOM?from?'react-dom';
import Create  from  './create'
import    TodoService  from  './service'
class??Root?extends??React.Component??{
    constructor(props) {
        super(props);
        this.service = new  TodoService();  //初始化類對象
    }
    handleCreate(title){  
        console.log(title.target.value)  //打印create.js中傳輸的數據
        this.service.create(title.target.value)  //調用todoserver的方法完成數據的持久化操作 
    }
    render(){
        return  (<div>
            hello world 
            <hr/>
            <Create  onCreate={this.handleCreate.bind(this)} />  {/*通過此處的傳遞將oncrete屬性傳遞到后端用于相關的處理*/}
        </div>)
    }
}
ReactDOM.render(<Root/>,document.getElementById('root'));

create.js組件內容

import  React  from  'react';
import { Card,Input } from 'antd';
import  'antd/lib/card/style'  //導入相關樣式表 
import 'antd/lib/Input/style'
//缺省導出無狀態組件react 中 
export default props  => (
    <Card title="請輸入" style={{ width: 300 }}>
        <Input  onPressEnter={(event) => props.onCreate(event)}/>  {/*此處通過外部的index.js中的數據傳遞
        將handleCreate 傳遞過來進行相關的處理操作,其被作為props攜帶進入此處參與相關的處理和調度操作*/}
    <p>測試代碼</p>
     </Card>
)

結果如下

react項目基本實踐

3 創建添加數據顯示問題

添加數據完成后顯示問題,需要創建用于列表顯示結果,需要創建的包如下,其仍然再src目錄下:Todo.js

import  React  from  'react'
import {  Checkbox,Card,Row,Col } from 'antd'
import  'antd/lib/card/style'
import  'antd/lib/row/style'
import  'antd/lib/card/style'
import  'antd/lib/checkbox/style'

export  default  props =>(
    <Card>
        <Row>
            <Col span={4}><Checkbox  /> }/></Col>
            <Col span={20}>{props.todo.title}</Col>
        </Row>
    </Card>
)

index.js代碼如下

import?React?from?'react';
import?ReactDOM?from?'react-dom';
import Create  from  './create'
import TodoService  from  './service'
import Todo from './Todo';
class??Root??extends?React.Component?{
    ??constructor?(props)??{
    ????super(props);
    ????this.service=new??TodoService();?
    ????this.state={todos:this.service.todos}?//變化引起的刷新操作
    ??}
    ??handleCreate?(event)??{

    ????this.service.create(event);
    ????this.setState({todos:this.service.todos});
    ??}

    ??render(){
    ????return(
    ????????<div>
    ??????????<Create?onCreate={this.handleCreate.bind(this)}?/>??{/*自己定義一個屬性,處理props事件的*/}
    ??????????{/*完成數據的顯示*/}
    ??????????{/*?{this.service.todos.forEach}??雖然遍歷,但不返回任何結果?*/}
    ??????????{this.service.todos.map(item=> <Todo? key={item.key} todo={item}?/>)}??{/*調用todo進行處理相關的函數問題,map后返回新的容器*/}
    ????????</div>
    ????);
    ??}
    }
    ReactDOM.render(<Root?/>,document.getElementById('root'));??//NewRoot(props)??

結果如下

react項目基本實踐

每添加一個元素,其會顯示該元素。但其在網頁刷新后其會不存在,但在localstorage中存儲所有的數據,因此需要處理裝載數據的函數。

4 數據持久化操作

修改代碼如下

import  store  from  'store' 
export  default  class TodoService{
    static NAMESPACE="todo"  //定義存儲前綴 
    todos= new Map();  //定義存儲容器 
    // 創建todo  
    constructor(){
        this.load();
    }
    load(){
        store.each((value,key) => {
            if (key.startsWith(TodoService.NAMESPACE))
                this.todos.set(key,value)
        }
        )} 

    create(title) { //定義函數,用于處理創建和存儲數據
        const todo = {  //定義value類型 
        key: TodoService.NAMESPACE+(new Date()).valueOf(),    /*毫秒時間戳*/
        title :title,  //定義相關類型 
        completed: false //定義數據狀態
        }
        this.todos.set(todo.key,todo);  //存儲至容器中
        //持久化處理
        store.set(todo.key,todo);
        return todo
    }
}

index.js 代碼修改結果如下

import?React?from?'react';
import?ReactDOM?from?'react-dom';
import Create  from  './create'
import TodoService  from  './service'
import Todo from './Todo';
import Filter  from  './filter'
import { set } from 'mobx';
class??Root??extends?React.Component?{
    ??constructor?(props)??{
    ????super(props);
    ????this.service=new??TodoService();?
    ??}
    ??handleCreate?(event)??{
    ????this.service.create(event);
    ????this.setState({todos:this.service.todos});
    ??}
    ??render(){
    ????return(
    ????????<div>
    ??????????<Create?onCreate={this.handleCreate.bind(this)}?/>??{/*自己定義一個屬性,處理props事件的*/}
    ??????????{/*完成數據的顯示*/}
    ??????????{[...this.service.todos.values()].map( item=> <Todo?todo={item}/>)}??{/*調用todo進行處理相關的函數問題,map后返回新的容器*/}
    ????????</div>
    ????);
    ??}
    }
    ReactDOM.render(<Root?/>,document.getElementById('root'));??//NewRoot(props)??
    //?Test(Root)(props)

最終結果如下

react項目基本實踐

5 后端狀態的修改實現

無論如何刷新,其最終結果都將會完全顯示

后端 completed 狀態為false和true的實現,其主要是通過checkbox 實現

Todo.js修改代碼如下

import?React??from??'react';
import??{Checkbox,Card,Row,Col}???from??'antd';
import??'antd/lib/row/style';
import?'antd/lib/card/style';
import?'antd/lib/Col/style';

//一條待辦事宜
export??default??props?=>?(
????<Card??style={{width:600}}>
????????<Row>
????????????<Col?span="4"><Checkbox?onChange={(event)  =>props.onChage(event.target.checked,props.todo.key)}/></Col>
????????????<Col?span="20">{props.todo.title}</Col>
????????</Row>?
??????</Card>?
);

后端service代碼

import  store  from  'store' 
export  default  class TodoService{
    static NAMESPACE="todo"  //定義存儲前綴 
    todos= new Map();  //定義存儲容器 
    // 創建todo  
    constructor(){
        this.load();
    }
    load(){
        store.each((value,key) => {
            if (key.startsWith(TodoService.NAMESPACE))
                this.todos.set(key,value)
        }
        )} 

    create(title) { //定義函數,用于處理創建和存儲數據
        const todo = {  //定義value類型 
        key: TodoService.NAMESPACE+(new Date()).valueOf(),    /*毫秒時間戳*/
        title :title,  //定義相關類型 
        completed: false //定義數據狀態
        }
        this.todos.set(todo.key,todo);  //存儲至容器中
        //持久化處理
        store.set(todo.key,todo);
        return todo
    }
    todochaService(key,checked){
        let todo=this.todos.get(key)  //獲取對應的值
        todo.completed=checked;  //賦值
        console.log(todo.completed,checked)
        this.todos.set(key,todo) //刷新map
        store.set(key,todo)  //刷新store 
    }
}

index.js端代碼如下

import?React?from?'react';
import?ReactDOM?from?'react-dom';
import Create  from  './create'
import TodoService  from  './service'
import Todo from './Todo';
class??Root??extends?React.Component?{
    ??constructor?(props)??{
    ????super(props);
    ????this.service=new??TodoService();?
    ??}
    ??handleCreate?(event)??{
    ????this.service.create(event);
    ????this.setState({todos:this.service.todos});
    ??}
    handleChange(checked,key)   //此處主要是用于處理后端的completed的變化,因此需要傳遞key和對應的觸發事件的值
        {
           console.log(key,checked) //打印key和對應的值
           this.service.todochaService(key,checked) 
        }
    ??render(){
    ????return(
    ????????<div>
    ??????????<Create?onCreate={this.handleCreate.bind(this)}?/>??{/*自己定義一個屬性,處理props事件的*/}
    ??????????{/*完成數據的顯示*/}
    ??????????{[...this.service.todos.values()].map( item=> <Todo? onChage={this.handleChange.bind(this)}  key={item.key} todo={item}/>)}??{/*調用todo進行處理相關的函數問題,map后返回新的容器*/}
    ????????</div>
    ????);
    ??}
    }
    ReactDOM.render(<Root?/>,document.getElementById('root'));??//NewRoot(props)??
    //?Test(Root)(props)

結果如下

react項目基本實踐

6 過濾查詢實現

創建相關過濾模塊,如下 仍然臨時存儲于src中,創建名為Filter.js,如下
Filter.js

測試返回結果

import  React  from  'react';
import { Select  } from 'antd';
const { Option } = Select;
import  'antd/lib/select/style';
export default  props  => (
  <Select
    showSearch
    style={{ width: 200 }} defaultValue="uncompleted"  onChange={(event) =>console.log(event)} > 
    <Option value="uncompleted">未完成</Option>
    <Option value="completed">已完成</Option>
    <Option value="all">全部</Option>
  </Select>
);

其中 defaultValue 用于顯示默認設置
onChange={(event) =>console.log(event)} 用于查看選擇引起的調度
<Option value="uncompleted">未完成</Option> 中中間的未完成用于顯示,而value用于實際觸發的傳值。

index.js中添加相關配置如下

import?React?from?'react';
import?ReactDOM?from?'react-dom';
import Create  from  './create'
import TodoService  from  './service'
import Todo from './Todo';
import  Filter  from  './filter'
class??Root??extends?React.Component?{
    ??constructor?(props)??{
    ????super(props);
    ????this.service=new??TodoService();?
    ??}
    ??handleCreate?(event)??{
    ????this.service.create(event);
    ????this.setState({todos:this.service.todos});
    ??}
    handleChange(checked,key)   //此處主要是用于處理后端的completed的變化,因此需要傳遞key和對應的觸發事件的值
        {
           console.log(key,checked) //打印key和對應的值
           this.service.todochaService(key,checked) 
        }
    ??render(){
    ????return(
    ????????<div>
    ??????????<Create?onCreate={this.handleCreate.bind(this)}?/>??{/*自己定義一個屬性,處理props事件的*/}
    ??????????{/*完成數據的顯示*/}
            <Filter />

    ??????????{[...this.service.todos.values()].map( item=> <Todo? onChage={this.handleChange.bind(this)}  key={item.key} todo={item}/>)}??{/*調用todo進行處理相關的函數問題,map后返回新的容器*/}
    ????????</div>
    ????);
    ??}
    }
    ReactDOM.render(<Root?/>,document.getElementById('root'));??//NewRoot(props)??
    //?Test(Root)(props)

結果如下

react項目基本實踐

選擇不同的選項會導致不同的觸發結果,此處便可作為其條件進行相關操作

配置觸發改變和相關顯示

index.js

import?React?from?'react';
import?ReactDOM?from?'react-dom';
import Create  from  './create'
import TodoService  from  './service'
import Todo from './Todo';
import  Filter  from  './filter'
class??Root??extends?React.Component?{
    ??constructor?(props)??{
    ????super(props);
    ????this.service=new??TodoService();?
        this.state={todos:this.service.todos}
        this.state={filter:"uncompleted"}
    ??}
    ??handleCreate?(event)??{
    ????this.service.create(event);
    ????this.setState({todos:this.service.todos});
    ??}
    handleChange(checked,key)   //此處主要是用于處理后端的completed的變化,因此需要傳遞key和對應的觸發事件的值
        {
           console.log(key,checked) //打印key和對應的值
           this.service.todochaService(key,checked) 
        }
    handleFliter(value){
        this.setState({filter:value})
        this.state.filter=value;  //修改狀態
        console.log(this.state.filter)
    }
    ??render(){
    ????return(
    ????????<div>
    ??????????<Create?onCreate={this.handleCreate.bind(this)}?/>??{/*自己定義一個屬性,處理props事件的*/}
    ??????????{/*完成數據的顯示*/}
              <Filter   onFilter={this.handleFliter.bind(this)}/>
    ??????????{[...this.service.todos.values()].filter(item  => {
                    let  fs=this.state.filter;
                    if (fs==="uncompleted")
                        if (item.completed===true)
                            return false  
                        else
                            return true  
                    if  (fs=== "completed") 
                        if (item.completed===true)
                            return  true  
                        else  
                            return  false
                    else 
                        return true
    }).map(item => <Todo? onChage={this.handleChange.bind(this)}  key={item.key} todo={item}/>)}??{/*調用todo進行處理相關的函數問題,map后返回新的容器*/}
    ????????</div>
    ????);
    ??}
    }
    ReactDOM.render(<Root?/>,document.getElementById('root'));??//NewRoot(props)??
    //?Test(Root)(props)

修改filter.js如下

import  React  from  'react';
import { Select  } from 'antd';
const { Option } = Select;
import  'antd/lib/select/style';
export default  props  => (
  <Select
    showSearch
    style={{ width: 200 }} defaultValue="uncompleted" onChange={event => props.onFilter(event)}>
    <Option value="uncompleted">未完成</Option>
    <Option value="completed">已完成</Option>
    <Option value="all">全部</Option>
  </Select>
);

結果如下

react項目基本實踐

react項目基本實踐

7 調整代碼布局

調整代碼布局,將顯示層(view)代碼調整到component目錄中包括create.js,filter.js,Todo.js和TodoApp.js(此處是將index.js的數據悉數移動到形成的),將后面的service層的代碼調整到service中,如下

react項目基本實踐

index.js 和 TodoApp.js修改如下

TodoApp.js

import?React?from?'react';
import Create  from  './create'
import TodoService  from  '../service/service'
import Todo from './Todo';
import  Filter  from  './filter'

export  default class  Root??extends?React.Component?{
    ??constructor?(props)??{
    ????super(props);
    ????this.service=new??TodoService();?
        this.state={todos:this.service.todos}
        this.state={filter:"uncompleted"}
    ??}
    ??handleCreate?(event)??{
    ????this.service.create(event);
    ????this.setState({todos:this.service.todos});
    ??}
    handleChange(checked,key)   //此處主要是用于處理后端的completed的變化,因此需要傳遞key和對應的觸發事件的值
        {
           console.log(key,checked) //打印key和對應的值
           this.service.todochaService(key,checked) 
        }
    handleFliter(value){
        this.setState({filter:value})
        this.state.filter=value;  //修改狀態
        console.log(this.state.filter)
    }
    ??render(){
    ????return(
    ????????<div>
    ??????????<Create?onCreate={this.handleCreate.bind(this)}?/>??{/*自己定義一個屬性,處理props事件的*/}
    ??????????{/*完成數據的顯示*/}
              <Filter   onFilter={this.handleFliter.bind(this)}/>
    ??????????{[...this.service.todos.values()].filter(item  => {
                    let  fs=this.state.filter;
                    if (fs==="uncompleted")
                        if (item.completed===true)
                            return false  
                        else
                            return true  
                    if  (fs=== "completed") 
                        if (item.completed===true)
                            return  true  
                        else  
                            return  false
                    else 
                        return true
    }).map(item => <Todo? onChage={this.handleChange.bind(this)}  key={item.key} todo={item}/>)}??{/*調用todo進行處理相關的函數問題,map后返回新的容器*/}
    ????????</div>
    ????);
    ??}
    }

index.js 如下

import?ReactDOM?from?'react-dom';
import?React?from?'react';
import  Root  from  './compoent/TodoApp';
ReactDOM.render(<Root?/>,document.getElementById('root'));??//NewRoot(props)??
    //?Test(Root)(props)

8 總結

渲染的事情歸TodoApp負責,并管理所有的狀態。
create負責顯示文本框,接受用戶輸入的待辦事宜。
TOdo,負責每一條數據的顯示和check變化
filter,主要負責一個狀態的filter的切換


service.js

todoservice 負責業務的處理,為了簡單,把數據處理也放在此處

狀態state的控制和修改有些麻煩,需要改進

三 服務改進

1 狀態監控改進

程序修改

TodoApp觀察TodoService中的變量的變化,如todos。可通過obserable 進行定義被檢查對象,通過 observer 進行檢測處理。


之前的TodoApp是同構service關聯到TodoService實例的,現在修改成了通過JSX元素屬性的方式傳遞,因此,需要修改index.js和TodoApp及后端。


service.js 修改如下

import  store  from  'store' 
import { observable } from "mobx";

export  default  class TodoService{
    static NAMESPACE="todo"  //定義存儲前綴 
    @observable  todos= new Map();  //定義存儲容器 
    // 創建todo  
    constructor(){
        this.load();
    }
    load(){
        store.each((value,key) => {
            if (key.startsWith(TodoService.NAMESPACE))
                this.todos.set(key,value)
        }
        )} 

    create(title) { //定義函數,用于處理創建和存儲數據
        const todo = {  //定義value類型 
        key: TodoService.NAMESPACE+(new Date()).valueOf(),    /*毫秒時間戳*/
        title :title,  //定義相關類型 
        completed: false //定義數據狀態
        }
        this.todos.set(todo.key,todo);  //存儲至容器中
        //持久化處理
        store.set(todo.key,todo);
        return todo
    }
    todochaService(key,checked){
        let todo=this.todos.get(key)  //獲取對應的值
        todo.completed=checked;  //賦值
        console.log(todo.completed,checked)
        this.todos.set(key,todo) //刷新map
        store.set(key,todo)  //刷新store 
    }
}

index.js修改如下

import?ReactDOM?from?'react-dom';
import?React?from?'react';
import  Root  from  './compoent/TodoApp';
import TodoService  from  './service/service'
const  service=new TodoService()

ReactDOM.render(<Root  service={service}?/>,document.getElementById('root'));?//通過外部傳值的方式實現

TodoApp.js如下

import?React?from?'react';
import Create  from  './create'
import Todo from './Todo';
import  Filter  from  './filter'
import {observer} from 'mobx-react';
@observer
export  default class  Root??extends?React.Component?{
    ??constructor?(props)??{
    ????super(props);
        this.state={filter:"uncompleted"}
    ??}
    ??handleCreate?(event)??{
    ????this.props.service.create(event); //此處通過index.js的方法進行傳值
    ??}
    handleChange(checked,key)   //此處主要是用于處理后端的completed的變化,因此需要傳遞key和對應的觸發事件的值
        {
           console.log(key,checked) //打印key和對應的值
           this.props.service.todochaService(key,checked) //此處也是
        }
    handleFliter(value){
        this.setState({filter:value})
        this.state.filter=value;  //修改狀態
        console.log(this.state.filter)
    }
    ??render(){
    ????return(
    ????????<div>
    ??????????<Create?onCreate={this.handleCreate.bind(this)}?/>??{/*自己定義一個屬性,處理props事件的*/}
    ??????????{/*完成數據的顯示*/}
              <Filter   onFilter={this.handleFliter.bind(this)}/>
    ??????????{[...this.props.service.todos.values()].filter(item  => { 
                    let  fs=this.state.filter;
                    if (fs==="uncompleted")
                        if (item.completed===true)
                            return false  
                        else
                            return true  
                    if  (fs=== "completed") 
                        if (item.completed===true)
                            return  true  
                        else  
                            return  false
                    else 
                        return true
    }).map(item => <Todo? onChage={this.handleChange.bind(this)}  key={item.key} todo={item}/>)}??{/*調用todo進行處理相關的函數問題,map后返回新的容器*/}
    ????????</div>
    ????);
    ??}
    }

2 復選框改變列表不刷新問題

復選框改變列表不刷新問題

運行一切為正常,就是有一點不方便,及checkbox點擊后,其不會發生重繪操作。


checkbox變化導致了TodoService 的todochaService 函數調用,修改相關屬性,但此處todos并未發生變化,只是修改其內部元素而已,解決方式是手動修改todos,使其發生重繪。

import  store  from  'store' 
import { observable } from "mobx";

export  default  class TodoService{
    static NAMESPACE="todo"  //定義存儲前綴 
    @observable  todos= new Map();  //定義存儲容器 
    // 創建todo  
    constructor(){
        this.load();
    }
    load(){
        store.each((value,key) => {
            if (key.startsWith(TodoService.NAMESPACE))
                this.todos.set(key,value)
        }
        )} 

    create(title) { //定義函數,用于處理創建和存儲數據
        const todo = {  //定義value類型 
        key: TodoService.NAMESPACE+(new Date()).valueOf(),    /*毫秒時間戳*/
        title :title,  //定義相關類型 
        completed: false //定義數據狀態
        }
        this.todos.set(todo.key,todo);  //存儲至容器中
        //持久化處理
        store.set(todo.key,todo);
        return todo
    }
    todochaService(key,checked){
        let todo=this.todos.get(key)  //獲取對應的值
        todo.completed=checked;  //賦值
        console.log(todo.completed,checked)
        this.todos.set(key,todo) //刷新map
        store.set(key,todo)  //刷新store 
        let temp=this.todos;
        this.todos = ()=>{};
        this.todos=temp;
    }

}

結果如下

react項目基本實踐

3 過濾數據方法調整

能夠將過濾數據的filter函數后移動到TodoService中。
在TodoService中提供todos屬性的getter,此處可直接將方法當成屬性來調用
相關修改如下

TodoApp.js修改如下

import?React?from?'react';
import Create  from  './create'
import Todo from './Todo';
import  Filter  from  './filter'
import {observer} from 'mobx-react';
@observer
export  default class  Root??extends?React.Component?{
    ??constructor?(props)??{
    ????super(props);
    ??}
    ??handleCreate?(event)??{
    ????this.props.service.create(event);
    ??}
    handleChange(checked,key)   //此處主要是用于處理后端的completed的變化,因此需要傳遞key和對應的觸發事件的值
        {
           console.log(key,checked) //打印key和對應的值
           this.props.service.todochaService(key,checked) 
        }
    handleFliter(value){
        this.props.service.setFilterState(value)
    }
    ??render(){
    ????return(
    ????????<div>
    ??????????<Create?onCreate={this.handleCreate.bind(this)}?/>??{/*自己定義一個屬性,處理props事件的*/}
    ??????????{/*完成數據的顯示*/}
              <Filter   onFilter={this.handleFliter.bind(this)}/>
    ??????????{this.props.service.todos.map(item => <Todo? onChage={this.handleChange.bind(this)}  key={item.key} todo={item}/>)}
    ????????</div>
    ????);
    ??}
    }

修改代碼如下

service.js修改如下

import  store  from  'store' 
import { observable,computed } from "mobx";

export  default  class TodoService{
    static NAMESPACE="todo"  //定義存儲前綴 
    @observable  _todos= new Map();  //定義存儲容器 
    @observable  filter="uncompleted"  //此處定義filter
    setFilterState(value){
        ????????this.filter?=?value;??//需要修改此處
        ????}
    @computed  //此處會加快響應速率
    get todos(){
        return  [...this._todos.values()]
        .filter(item  => {
            let  fs=this.filter;
            if (fs==="uncompleted")
                if (item.completed===true)
                    return false  
                else
                    return true  
            if  (fs=== "completed") 
                if (item.completed===true)
                    return  true  
                else  
                    return  false
            else 
                return true
        });
    }

    // 創建todo  
    constructor(){
        this.load();
    }
    load(){
        store.each((value,key) => {
            if (key.startsWith(TodoService.NAMESPACE))
                this._todos.set(key,value)
        }
        )} 

    create(title) { //定義函數,用于處理創建和存儲數據
        const todo = {  //定義value類型 
        key: TodoService.NAMESPACE+(new Date()).valueOf(),    /*毫秒時間戳*/
        title :title,  //定義相關類型 
        completed: false //定義數據狀態
        }
        this._todos.set(todo.key,todo);  //存儲至容器中
        //持久化處理
        store.set(todo.key,todo);
        return todo
    }
    todochaService(key,checked){
        let todo=this._todos.get(key)  //獲取對應的值
        todo.completed=checked;  //賦值
        console.log(todo.completed,checked)
        this._todos.set(key,todo) //刷新map
        store.set(key,todo)  //刷新store 
        let temp=this._todos;
        this._todos = ()=>{};
        this._todos=temp;
    }   
}

4 處理輸入待辦事宜自動刷新問題

import  store  from  'store' 
import { observable,computed } from "mobx";

export  default  class TodoService{
    static NAMESPACE="todo"  //定義存儲前綴 
    @observable  _todos= new Map();  //定義存儲容器 
    @observable  filter="uncompleted"  //此處定義filter
    setFilterState(value){
        ????????this.filter?=?value;??//需要修改此處
        ????}
    @computed
    get todos(){
        return  [...this._todos.values()]
        .filter(item  => {
            let  fs=this.filter;
            if (fs==="uncompleted")
                if (item.completed===true)
                    return false  
                else
                    return true  
            if  (fs=== "completed") 
                if (item.completed===true)
                    return  true  
                else  
                    return  false
            else 
                return true
        });
    }
    flush (){  //強制刷新步驟
        let temp=this._todos;
        this._todos = ()=>{};
        this._todos=temp;
    }
    // 創建todo  
    constructor(){
        this.load();
    }
    load(){
        store.each((value,key) => {
            if (key.startsWith(TodoService.NAMESPACE))
                this._todos.set(key,value)
        }
        )} 

    create(title) { //定義函數,用于處理創建和存儲數據
        const todo = {  //定義value類型 
        key: TodoService.NAMESPACE+(new Date()).valueOf(),    /*毫秒時間戳*/
        title :title,  //定義相關類型 
        completed: false //定義數據狀態
        }
        this._todos.set(todo.key,todo);  //存儲至容器中
        //持久化處理
        store.set(todo.key,todo);
        this.flush();
        return todo
    }
    todochaService(key,checked){
        let todo=this._todos.get(key)  //獲取對應的值
        todo.completed=checked;  //賦值
        console.log(todo.completed,checked)
        this._todos.set(key,todo) //刷新map
        store.set(key,todo)  //刷新store 
        this.flush()
    }   
}

四 部署相關事宜

1 編寫python端配置,及后端服務配置

1 安裝模塊

pip install  aiohttp

2 編寫代碼

#!/usr/bin/poython3.6
#conding:utf-8
from  aiohttp  import  web,log
import logging
import  json

async  def  indexhandle(request:web.Request):
    return   web.Response(text='welcom  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):
    print (request.method)
    print (request.match_info)
    print (request.query_string)

    js=await  request.json() #協程是一個一個迭代,獲取json字符串提交數據
    print (js,type(js))

    text=dict(await request.post()) #此處是一個可迭代對象,傳統post提交//postman中使用此種方式進行提交處>理的
    print (text,type(text))

    js.update(text) #字典的合并  {}.update(**js,**text)
    res=json.dumps(js)  #json化,將其轉換成python的字符串
    print  (res)

    return  web.Response(text=res,status=201)

app=web.Application()
app.router.add_get('/',indexhandle)
app.router.add_get('/{id}',handle)
app.router.add_post('/todo',todopost)

app.logger.setLevel(level=logging.NOTSET)  #最底級別
web.run_app(app,host='0.0.0.0',port=8080)

3 啟動如下

python  test.py   &

4 結果如下

react項目基本實踐

2 前端

1 查看后端IP地址和相關監聽端口

本機服務器端IP地址為192.168.1.200,監聽端口為8080

react項目基本實踐

2 修改webpack.config.dev.js 相關反響代理端配置如下

react項目基本實踐

3 重啟訪問如下

訪問跟根

react項目基本實踐

訪問id

react項目基本實踐

訪問todo,上述只支持JSON格式,其他格式訪問則不能正常訪問

react項目基本實踐

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

金塔县| 阳信县| 察哈| 静乐县| 安庆市| 赤城县| 双柏县| 辉县市| 莒南县| 宜黄县| 育儿| 杭州市| 类乌齐县| 奉贤区| 泸水县| 太保市| 绥滨县| 山东省| 合江县| 乌什县| 普安县| 凤庆县| 内乡县| 徐州市| 长春市| 喀什市| 剑阁县| 福清市| 锡林浩特市| 军事| 泸西县| 建德市| 攀枝花市| 定陶县| 西贡区| 九江市| 甘肃省| 惠州市| 敖汉旗| 沂源县| 广南县|