entire页面划分
entire-filter
实现效果:
import PropTypes from "prop-types";
import React, { memo, useState } from "react";
import { FilterWrapper } from "./style";
import filterData from "@/assets/data/filter_data.json";
import classNames from "classnames";
const EntireFilter = memo((props) => {
const [selectItems, setSelectItems] = useState([]);
function itemClickHandle(item) {
const newItems = [...selectItems];
if (selectItems.includes(item)) {//移除操作
let selectIndex = selectItems.findIndex((v) => v === item);
newItems.splice(selectIndex, 1);
} else {//添加操作
newItems.push(item);
}
setSelectItems(newItems);
}
return (
<FilterWrapper>
<div className="filter">
{filterData.map((item, index) => {
return (
<div
onClick={(e) => itemClickHandle(item)}
className={classNames("itme", { active: selectItems.includes(item) })}
key={item}
>
{item}
</div>
);
})}
</div>
</FilterWrapper>
);
});
EntireFilter.propTypes = {};
export default EntireFilter;
import styled from "styled-components";
export const FilterWrapper = styled.div`
position: fixed;
z-index: 99;
left: 0;
right: 0;
top: 80px;
display: flex;
align-items: center;
height: 48px;
padding-left: 16px;
border-bottom: 1px solid #f2f2f2;
background-color: #fff;
.filter {
display: flex;
.itme {
margin: 0 4px 0 8px;
padding: 6px 12px;
border: 1px solid #dce0e0;
border-radius: 4px;
color: #484848;
cursor: pointer;
&.active {
background: #008489;
border: 1px solid #008489;
color: #ffffff;
}
}
}
`;
全部-房间列表数据获取和管理是方式
- redux
export const CHANGE_CURRENT_PAGE = "entire/change_current_page";
export const CHANGE_ROOM_LIST = "entire/change_room_list";
export const CHANGE_TOTAL_COUNT = "entire/change_total_count";
import * as actionTypes from "./constants";
const initialState = {
currentPage: 0, //当前页码
roomList: [], //房间列表
totalCount: 0, //总数居个数
};
function reducer(state = initialState, action) {
switch (action.type) {
case actionTypes.CHANGE_CURRENT_PAGE:
return { ...state, currentPage: action.currentPage };
case actionTypes.CHANGE_ROOM_LIST:
return { ...state, roomList: action.roomList };
case actionTypes.CHANGE_TOTAL_COUNT:
return { ...state, totalCount: action.totalCount };
default:
return state;
}
}
export default reducer;
import * as actionTypes from "./constants";
export const changeCurrentPageAction = (currentPage) => ({
type: actionTypes.CHANGE_CURRENT_PAGE,
currentPage,
});
export const changeRoomListAction = (roomList) => ({
type: actionTypes.CHANGE_ROOM_LIST,
roomList,
});
export const changeTotalCountAction = (totalCount) => ({
type: actionTypes.CHANGE_TOTAL_COUNT,
totalCount,
});
统一导出
import reducer from "./reducer";
export default reducer;
放在store中:
import { configureStore } from "@reduxjs/toolkit";
import homeReducer from "./modules/home";
import entireReducer from "./modules/entire";
const store = configureStore({
reducer: {
home: homeReducer,
entire: entireReducer,
},
});
export default store;
组件中派发action
import React, { memo, useEffect } from "react";
import { EntireWrapper } from "./style";
import EntireFilter from "./c-cpns/entire-filter";
import EntireRooms from "./c-cpns/entire-rooms";
import EntirePagination from "./c-cpns/entire-pagination";
import { useDispatch } from "react-redux";
import { fetchRoomListAction } from "@/store/modules/entire/createActions";
const Entire = memo(() => {
// 发送网络请求,获取数据,并且保存当前的页面...
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchRoomListAction());
});
return (
<EntireWrapper>
<EntireFilter />
<EntireRooms />
<EntirePagination />
</EntireWrapper>
);
});
export default Entire;
redux中异步网络请求
// 异步
export const fetchRoomListAction = () => {
// 新的函数
return async (dispatch, getState) => {
// 1.根据页码获取最新的数据
const currentPage = getState().entire.currentPage;
// 网络请求
const res = await getEntireRoomList(currentPage * 20); //偏移量 = 当前页 * 每页大小
// 2.获取到最新的数据,保存在redux的store中
const roomList = res.list;
const totalCount = res.totalCount;
// 派发action
dispatch(changeRoomListAction(roomList));
dispatch(changeTotalCountAction(totalCount));
};
};
store -> modules -> entire -> createActions.js 全部代码:
import { getEntireRoomList } from "@/services/modules/entire";
import * as actionTypes from "./constants";
export const changeCurrentPageAction = (currentPage) => ({
type: actionTypes.CHANGE_CURRENT_PAGE,
currentPage,
});
export const changeRoomListAction = (roomList) => ({
type: actionTypes.CHANGE_ROOM_LIST,
roomList,
});
export const changeTotalCountAction = (totalCount) => ({
type: actionTypes.CHANGE_TOTAL_COUNT,
totalCount,
});
// 异步
export const fetchRoomListAction = () => {
// 新的函数
return async (dispatch, getState) => {
// 1.根据页码获取最新的数据
const currentPage = getState().entire.currentPage;
// 网络请求
const res = await getEntireRoomList(currentPage * 20); //偏移量 = 当前页 * 每页大小
// 2.获取到最新的数据,保存在redux的store中
const roomList = res.list;
const totalCount = res.totalCount;
// 派发action
dispatch(changeRoomListAction(roomList));
dispatch(changeTotalCountAction(totalCount));
};
};
logo点击跳转到home页
import React, { memo } from "react";
import { LeftWrapper } from "./style";
import logo from "@/assets/img/logo.png";
import { useNavigate } from "react-router-dom";
const HeaderLeft = memo(() => {
const navigate = useNavigate();
function logoClickHandle() {
navigate("/home");
}
return (
<LeftWrapper>
<img onClick={logoClickHandle} className="logo" alt="logo" src={logo} />
</LeftWrapper>
);
});
export default HeaderLeft;
蒙版和分页器
import PropTypes from "prop-types";
import React, { memo } from "react";
import { RoomsWrapper } from "./style";
import { shallowEqual, useSelector } from "react-redux";
import RoomItem from "@/components/room-item";
const EntireRooms = memo((props) => {
// 从redux中获取数据
const { roomList, totalCount, isLoading } = useSelector(
(state) => ({
roomList: state.entire.roomList,
totalCount: state.entire.totalCount,
isLoading: state.entire.isLoading,
}),
shallowEqual
);
return (
<RoomsWrapper>
<div className="title">{totalCount}多处住所</div>
<div className="list">
{roomList.map((item) => {
return <RoomItem itemData={item} itemWidth="20%" key={item._id} />;
})}
</div>
{/* 蒙层 */}
{isLoading && <div className="cover"></div>}
</RoomsWrapper>
);
});
EntireRooms.propTypes = {};
export default EntireRooms;
import styled from "styled-components";
export const RoomsWrapper = styled.div`
padding: 40px 20px;
position: relative;
.title {
font-size: 22px;
font-weight: 700;
color: #222;
margin: 30px 0 10px 10px;
}
.list {
display: flex;
flex-wrap: wrap;
}
/* 蒙层 */
> .cover {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(255, 255, 255, 0.8);
}
`;
isLoading 控制显示隐藏:
import * as actionTypes from "./constants";
const initialState = {
currentPage: 0, //当前页码
roomList: [], //房间列表
totalCount: 0, //总数居个数
isLoading: false,
};
function reducer(state = initialState, action) {
switch (action.type) {
case actionTypes.CHANGE_CURRENT_PAGE:
return { ...state, currentPage: action.currentPage };
case actionTypes.CHANGE_ROOM_LIST:
return { ...state, roomList: action.roomList };
case actionTypes.CHANGE_TOTAL_COUNT:
return { ...state, totalCount: action.totalCount };
case actionTypes.CHANGE_IS_LOADING:
return { ...state, isLoading: action.isLoading };
default:
return state;
}
}
export default reducer;
网络请求前后切换状态:
dispatch(changeIsLoadingAction(true)); // 网络请求
const res = await getEntireRoomList(currentPage * 20); //偏移量 = 当前页 * 每页大小
dispatch(changeIsLoadingAction(false));
import { getEntireRoomList } from "@/services/modules/entire";
import * as actionTypes from "./constants";
export const changeCurrentPageAction = (currentPage) => ({
type: actionTypes.CHANGE_CURRENT_PAGE,
currentPage,
});
export const changeRoomListAction = (roomList) => ({
type: actionTypes.CHANGE_ROOM_LIST,
roomList,
});
export const changeTotalCountAction = (totalCount) => ({
type: actionTypes.CHANGE_TOTAL_COUNT,
totalCount,
});
export const changeIsLoadingAction = (isLoading) => ({
type: actionTypes.CHANGE_IS_LOADING,
isLoading,
});
// 异步
export const fetchRoomListAction = () => {
// 新的函数
return async (dispatch, getState) => {
// 1.根据页码获取最新的数据
const currentPage = getState().entire.currentPage;
dispatch(changeIsLoadingAction(true));
// 网络请求
const res = await getEntireRoomList(currentPage * 20); //偏移量 = 当前页 * 每页大小
dispatch(changeIsLoadingAction(false));
// 2.获取到最新的数据,保存在redux的store中
const roomList = res.list;
const totalCount = res.totalCount;
// 派发action
dispatch(changeRoomListAction(roomList));
dispatch(changeTotalCountAction(totalCount));
};
};
分页
import React, { memo } from "react";
import { PaginationWrapper } from "./style";
import Pagination from "@mui/material/Pagination";
import { shallowEqual, useDispatch, useSelector } from "react-redux";
import { fetchRoomListAction } from "@/store/modules/entire/createActions";
import { changeCurrentPageAction } from "@/store/modules/entire/createActions";
const EntirePagination = memo((props) => {
const { totalCount } = useSelector(
(state) => ({
totalCount: state.entire.totalCount,
}),
shallowEqual
);
const dispatch = useDispatch();
const totalPage = Math.ceil(totalCount / 20);
function clickHandle(e, page) {
dispatch(changeCurrentPageAction(page));
dispatch(fetchRoomListAction());
}
return (
<PaginationWrapper>
<Pagination onChange={clickHandle} count={totalPage} color="secondary" />
</PaginationWrapper>
);
});
export default EntirePagination;
import styled from "styled-components";
export const PaginationWrapper = styled.div`
display: flex;
justify-content: center;
`;
分页效果: