zoukankan      html  css  js  c++  java
  • 从零开始,搭建一个简单的购物平台(七)

    从零开始,搭建一个简单的购物平台(六):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",  200 },
          {
            align: "center",
            title: "邮箱",
            dataIndex: "mailaddress",
             200,
            render: (text, data) => {
              return <div>{text + data.mailurl}</div>;
            },
          },
          {
            align: "center",
            title: "密码",
            dataIndex: "password",
             300,
          },
          {
            align: "center",
            title: "头像",
            dataIndex: "headPic",
             150,
            render: (imgPath) => {
              return (
                <img
                  src={FilePath + imgPath}
                  alt=""
                  style={{  60, margin: "0 auto" }}
                />
              );
            },
          },
          {
            align: "center",
            title: "性别",
            dataIndex: "sex",
             200,
            render: (sex) => {
              return <div>{sex == "man" ? "男" : "女"}</div>;
            },
          },
          {
            align: "center",
            title: "收货地址",
            dataIndex: "alladdress",
             200,
            render: (text, data, index) => {
              return <div>{text.join("-") + data.address}</div>;
            },
          },
          {
            align: "center",
            title: "个性签名",
            dataIndex: "descript",
             200,
          },
          {
            align: "center",
            title: "用户类型",
            dataIndex: "userType",
             200,
            render: (type) => {
              return <div>{type == "admin" ? "管理员" : "用户"}</div>;
            },
          },
          {
            align: "center",
            title: "注册时间",
            dataIndex: "time",
             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 (
          <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或者初始状态值对相对应的组件进行使用,大大提升代码效率

  • 相关阅读:
    人工智能背后的故事
    idea 开发插件。
    安卓工作室 Android studio 或 Intellij IDEA 美化 修改 汉化 酷炫 装逼 Android studio or Intellij IDEA beautify modify Chinesization cool decoration
    安卓工作室 android studio文件和代码模板,以及汉化出错问题
    安卓工作室 android studio 汉化后,报错。 设置界面打不开。Can't find resource for bundle java.util.PropertyResourceBundle, key emmet.bem.class.name.element.separator.label
    android studio的汉化 教程 及解析
    安卓工作室Android Studio 快捷键
    安卓工作室 android studio 的 汉化 美化 定制 Android studio's Chinesization beautification customization
    VR开发 VR development
    Lakeshore 中文开发界面,示例项目,飞机大战 等 Lakeshore Chinese development interface, sample project, aircraft war, etc
  • 原文地址:https://www.cnblogs.com/HelloWorld-Yu/p/13514435.html
Copyright © 2011-2022 走看看