一、登錄功能:antd-Form、localStorage
1.登錄界面與首頁實現
1)兩個界面路由注冊,通過判斷本地是否有用戶登錄數據
有:---> <Route path='/' component={Admin} /> (作為的根路徑)
無:---> <Route path='/login' component={Login} />
2.表單數據收集
1)輸入過程數據驗證是否符合要求
2) 表單提交數據驗證 --> 通過發起登錄請求 --> 跳轉到根路由
在這個過程中需要往本地存儲用戶信息,並通過memoryUtil 將數據傳給首頁顯示
3. 首頁排版:antd -- Layout
1)側邊欄菜單實現:通過數據遍歷展現到頁面
2)權限驗證:根據用戶menus數據,決定側邊欄菜單功能展示
3)頭部
退出功能:antd --- Modal 、 退出后本地用戶數據清除,跳轉到登錄路由
時間、天氣動態展示:時間格式化Utils,高德天氣接口
標題展示:根據當前路徑匹配標題
4)home內容區:antd組件
二、 商品 ---- 品類管理:品類增加、修改、獲取
1.接口准備
包括接口請求使用axios封裝為一個函數,再分別創建不同類別的接口函數(reqAdd--、reqUpdate--)
目的:方便接口傳參而避免造成代碼冗余
//獲取分類列表 export const reqCategoryList = (parentId)=> ajax('/manage/category/list',{parentId}) //添加分類列表 export const reqAddCategory = (parentId,categoryName)=> ajax('/manage/category/add',{parentId,categoryName},'POST') //更新分類列表 export const reqUpdateCategory = (categoryId,categoryName)=> ajax('/manage/category/update',{categoryId,categoryName},'POST')
2. 品類管理路由組件實現--數據初始化
1)antd---Card模塊---Table模塊
2) 組件加載完后生命周期:請求數據(這是一個通用數據更新函數)、初始化數據
componentDidMount(){ this.inintColumns() this.setCategory() }
3)二級頁面數據初始化:根據接口參數不同,請求不同數據(利用Table性質拿到對應點擊數據 ),實現需要顯示或隱藏部分
3. 品類管理路由組件實現--數據修改
1)antd---Modal模塊---Form表單提交
2)拿到表單數據(函數傳參setForm)---數據驗證通過后調更新接口函數
updateCategory = ()=>{ const categoryId = this.category._id //表單驗證:通過后才處理 this.form.validateFields() .then(async (values) =>{ //隱藏確認框 this.setState({ isModalVisible: 0, }) const {categoryName} = values //清空輸入框 //this.form.resetFields() const result = await reqUpdateCategory(categoryId,categoryName) if(result.status === 0){ //重新展示類別列表 message.success('修改成功') this.setCategory() } }) .catch((err)=>{ message.info('請輸入分類名稱') }) }
3)注意:每次點擊一項修改時,輸入框都應該匹配對應修改項,這里需要:
a. 清除前一次輸入內容
b. 傳值:通過props,將放在實例的對應category : this.category 傳給form表單
c. this.category 是在點擊顯示模態框的時候放在實例上的
//模態框部分 destroyOnClose={true} 清除上次表單內容 <Modal title="更新" visible={isModalVisible===2? true:false} onOk={this.updateCategory} onCancel={this.handleCancel} destroyOnClose={true} > <UpdateForm categoryName={name} setForm = {(form)=>{this.form = form}}/> </Modal> //表單部分 initialValue={categoryName} 初始值 <Form ref={this.formRef}> <Item name="categoryName" initialValue={categoryName} rules={[ { required: true, message: '分類名稱必須輸入' }, ]} > {/* ----注意 <Form.Item /> 只會對它的直接子元素綁定表單功能 */} <Input placeholder="輸入分類的名字" /> </Item> </Form>
三、 商品 ---- 商品管理:商品增加、修改、詳情
1. 商品列表初始化:antd-Table 來幫忙實現后台分頁獲取數據
請求獲取商品接口,每次點擊下一頁時才發請求拿數據
注意:1)當頁面初始化時,當前請求page為1,后台會返回total總數,table根據total頁面展示頁數
2)頁面改變時會將當前頁數作為回調傳給接口繼續獲取下一頁的數據
<Card title={title} extra={extra}> <Table dataSource={products} columns={columns} bordered rowKey='_id' loading={loading} pagination= {{ defaultPageSize:PAGE_SIZE, total, onChange:(pageNum)=>{this.setProducts(pageNum)} // 頁碼改變的回調,參數是頁碼數和每頁條數 }} /> </Card>
2. 頁面功能:
1)按名稱搜索、按內容搜索
收集select --value 和input內容:select與input綁定onChange監聽回調,value改變即傳入數據----this.setState
點擊搜索,拿參數發請求
注意坑:
搜索出的列表頁面會根據當前頁面下標顯示,所以需要在搜索的時候傳初始參pageNum=1
這里的接口分為名稱、內容兩個,可合並處理,注意變量作為屬性名
//搜索商品 (productName/productDesc) export const reqSearchProducts = ({pageNum,pageSize,searchName,searchType})=> ajax('/manage/product/search',{ pageNum, pageSize, [searchType]:searchName })
2)商品狀態(上/下架)
得到當前點擊商品數據,進行接口傳參,商品status需取反
3)展示詳情頁
得到當前點擊商品數據 ---- 傳給詳情組件(路由組件傳數據 this.props.history.push('/product/detail',product)})
---- 所屬分類需要根據parentId與categoryId獲取(發請求) ---- 頁面渲染
4)修改與添加功能,同一路由組件實現
① 點擊修改時需展現當前商品信息,點擊添加不需要,根據判斷上級路由傳沒傳參來決定修改還是添加
② 所屬分類:使用antd --- Cascader實現(組件一加載需要初始化一級分類與二級分類)
③ 級聯的二級分類是動態加載的
注意坑:更新狀態值this.setState({})到時候 解構賦值
④ 商品圖片上傳:
添加時:antd-Upload 直接請求接口
修改時:需要初始化圖片列表,將imgs數組傳過來渲染到頁面
<Upload action="/manage/img/upload" // 上傳請求接口 accept='image/*'//上傳文件類型 name='image' //請求參數名 listType="picture-card" fileList={fileList} //上傳文件數量 onPreview={this.handlePreview} // 圖片顯示大圖的回調 onChange={this.handleChange} // 圖片上傳過程中的回調 > {fileList.length >= 2 ? null : uploadButton} </Upload>
⑤ 富文本編輯器:react-draft-wysiwyg