从零开始,搭建一个简单的购物平台(六):https://blog.csdn.net/time_____/article/details/105440818
项目源码(持续更新):https://gitee.com/DieHunter/myCode/tree/master/shopping
到现在为止,项目前后端功能已实现登录,token获取验证,上传头像,添加用户,这篇文章主要讲述实现前后端用户列表分页查找,模糊查询,用户列表渲染功能
- 首先是分页查找,后端实现方式通过数据库查找表的长度,配合数据库函数skip(n)(跳过前n条数据),和limit(m)(向后查找m条数据),通过db.find().skip((page - 1) * pageSize).limit(pageSize)(page代表第几页,从0开始,第一页则不需要跳过。pageSize表示分页后每页数据条数),所以我们在command.js中新建两个方法,用于查询表的长度和关键字查询并分页
/* 查询分页
* @param {object} mod 数据库model
* @param {number} sort 排序顺序 负数倒序 正数顺序
* @param {number} page 当前页数
* @param {number} pageSize 分页大小
* @param {object} pageSize 关键字模糊查询
*/
static async findByPage(mod,sort,page,pageSize,keyWord) {
//分页查
return await mod
.find(keyWord)
.sort(sort)
.skip((page - 1) * pageSize)
.limit(pageSize);
}
/* 查询分页
* @param {object} mod 数据库model
* @param {number} pageSize 分页大小
*/
static async getTotalPage(mod,pageSize) {
let allNum = await mod.find().estimatedDocumentCount();
return { totalPage: parseInt(allNum / pageSize) + 1,allNum };
}
- 在users.js中添加获取用户列表的接口,通过电子邮件或者用户名查找,分页
router.get(Config.ServerApi.userList,Util.checkToken,async (req,res) => {
if (res._data.userTokenType != "admin") {
//非管理员
res.send({
result: -999,msg: "请用管理员账号登录",});
return;
}
let total = await getTotalPage(Mod,res._data.pageSize);
let query = new RegExp(res._data.keyWord,"i"); //模糊查找正则条件
res.send({
result: 1,data: {
page: res._data.page,pageSize: res._data.pageSize,totalPage: total.totalPage,allNum: total.allNum,list: await findByPage(
Mod,{
time: res._data.sort,},res._data.page,res._data.pageSize,res._data.keyWord.length
? {
$or: [
{
mailaddress: query,{
username: query,],}
: {}
),msg: "查找成功",});
});
后端部分实现完成后,开始编写前端,需要用到表格组件,分页组件和input查找组件,这里可以将表格组件单独写出来,写成我们自己的组件,以供后期商品列表重复使用
- 先配置一下用户表格字段,封装到一个class里
import React from "react";
import {
Button,Popconfirm,} from "antd";
import config from "../../config/config";
const { FilePath } = config;
export default class UserTable {
constructor(_this) {
return [
{ align: "center",title: "用户名",dataIndex: "username",width: 200 },{
align: "center",title: "邮箱",dataIndex: "mailaddress",width: 200,render: (text,data) => {
return <div>{text + data.mailurl}</div>;
},title: "密码",dataIndex: "password",width: 300,title: "头像",dataIndex: "headPic",width: 150,render: (imgPath) => {
return (
<img
src={FilePath + imgPath}
alt=""
style={{ width: 60,margin: "0 auto" }}
/>
);
},title: "性别",dataIndex: "sex",render: (sex) => {
return <div>{sex == "man" ? "男" : "女"}</div>;
},title: "收货地址",dataIndex: "alladdress",data,index) => {
return <div>{text.join("-") + data.address}</div>;
},title: "个性签名",dataIndex: "descript",title: "用户类型",dataIndex: "userType",render: (type) => {
return <div>{type == "admin" ? "管理员" : "用户"}</div>;
},title: "注册时间",dataIndex: "time",];
}
}
- 在表格渲染前判断一下表格类型,是显示用户还是商品,达到组件复用功能,将分页组件与pageconfig绑定,达到切换页面的效果
import React from "react";
import {
Table,Button,Card,Pagination,Input,Col,Row,} from "antd";
import userTab from "./userTab";
import { PlusOutlined } from "@ant-design/icons";
const { Search } = Input;
export default class ListTable extends React.Component {
state = {
tableType: this.props.tableType,pageConfig: {
totalPage: 0,page: 0,pageSize: 0,allNum: 0,columns: [],list: [],};
componentDidMount() {
if (this.state.tableType == "user") {
this.setState({
columns: new userTab(this)
});
} else {
}
this.props.onTableRef(this);
}
render() {
return (
<Card title="用户列表">
<Row gutter={16}>
<Col span={12}>
<Button onClick={this.props.showDrawer} type="primary">
<PlusOutlined />
新增用户
</Button>
</Col>
<Col span={12}>
<Search
style={{ float: "right" }}
placeholder="输入用户名/邮箱"
enterButton="查找"
size="large"
allowClear
onSearch={(val) => {
let { pageConfig } = this.state;
pageConfig.keyWord = val;
this.setState({
pageConfig,});
this.props.changePage(pageConfig);
}}
/>
</Col>
</Row>
<Table
scroll={{ x: 2000 }}
rowKey={(record) => record._id}
columns={this.state.columns}
dataSource={this.state.list}
pagination={false}
></Table>
<Pagination
style={{ marginTop: 50 }}
hideOnSinglePage
total={this.state.pageConfig.allNum}
current={this.state.pageConfig.page}
pageSize={this.state.pageConfig.pageSize}
showSizeChanger
showQuickJumper
showTotal={(total) => `共 ${total} 条`}
onChange={this.changePage}
onShowSizeChange={this.changePage}
/>
</Card>
);
}
changePage = (page,pageSize) => {
let pageConfig = this.state.pageConfig;
pageConfig.page = page;
pageConfig.pageSize = pageSize;
this.setState({
pageConfig,});
this.props.changePage(pageConfig);
};
}
- 最后在userlist中调用,与表格中的page达到一个数据双向绑定效果
import React from "react";
import ListTable from "../../../components/table/table";
import {
message,} from "antd";
import config from "../../../config/config";
const { ServerApi,StorageName } = config;
export default class UserList extends React.Component {
state = {
userType: "adduser",pageConfig: {
token: this.$utils.getStorage(StorageName.token),keyWord: "",page: 1,pageSize: 2,totalPage: 1,sort: 1,};
componentDidMount() {
this.getUserList();
}
render() {
return (
<div>
<ListTable
tableType="user"
onTableRef={(child) => {
this.tableChild = child;
}}
showDrawer={this.showDrawer}
changePage={this.changePage}
></ListTable>
<ListDrower
getUserList={this.getUserList}
userType={this.state.userType}
onDrowerRef={(child) => {
this.drawerChild = child;
}}
></ListDrower>
</div>
);
}
showDrawer = () => {
this.drawerChild.showDrawer();
};
changePage = (pageConfig) => {
this.setState({ pageConfig });
this.getUserList();
};
getUserList = () => {
let data = { ...this.state.pageConfig };
this.$axios
.get(ServerApi.user.userList,{
params: { crypto: this.$crypto.setCrypto(data) },})
.then((res) => {
let { list,totalPage,allNum } = res.data;
let { pageConfig } = this.state;
pageConfig.allNum = allNum;
pageConfig.totalPage = totalPage;
this.tableChild.setState({ pageConfig,list });
})
.catch((err) => {});
};
}
- 全部完成后,测试一下
总结
在组件化开发的前端代码中,组件复用可以使代码可维护性提升,通过修改state或者初始状态值对相对应的组件进行使用,大大提升代码效率
原文地址:https://blog.csdn.net/time_____
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。