从零开始,搭建一个简单的购物平台(七)

从零开始,搭建一个简单的购物平台(六):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 
{text + data.mailurl}
; }, }, { align: "center", title: "密码", dataIndex: "password", width: 300, }, { align: "center", title: "头像", dataIndex: "headPic", width: 150, render: (imgPath) => { return ( ); }, }, { align: "center", title: "性别", dataIndex: "sex", width: 200, render: (sex) => { return
{sex == "man" ? "男" : "女"}
; }, }, { align: "center", title: "收货地址", dataIndex: "alladdress", width: 200, render: (text, data, index) => { return
{text.join("-") + data.address}
; }, }, { align: "center", title: "个性签名", dataIndex: "descript", width: 200, }, { align: "center", title: "用户类型", dataIndex: "userType", width: 200, render: (type) => { return
{type == "admin" ? "管理员" : "用户"}
; }, }, { align: "center", title: "注册时间", dataIndex: "time", width: 200, }, ]; } }
  • 在表格渲染前判断一下表格类型,是显示用户还是商品,达到组件复用功能,将分页组件与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 (
      
        
          
            
          
          
             {
                let { pageConfig } = this.state;
                pageConfig.keyWord = val;
                this.setState({
                  pageConfig,
                });
                this.props.changePage(pageConfig);
              }}
            />
          
        
         record._id}
          columns={this.state.columns}
          dataSource={this.state.list}
          pagination={false}
        >
`共 ${total} 条`} onChange={this.changePage} onShowSizeChange={this.changePage} />
); } 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 (
      
{ this.tableChild = child; }} showDrawer={this.showDrawer} changePage={this.changePage} > { this.drawerChild = child; }} >
); } 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或者初始状态值对相对应的组件进行使用,大大提升代码效率

你可能感兴趣的:(Node.js,Vue,React,node.js,reactjs)