ゼロから始めて、簡単なショッピングプラットフォームを構築します(6):https://blog.csdn.net/time_____/article/details/105440818
プロジェクトのソースコード(継続的な更新):https://gitee.com/DieHunter/myCode/ツリー/マスター/ショッピング
これまで、プロジェクトのフロントエンドとバックエンドの機能は、ログイン、トークンの取得と検証、アバターのアップロード、ユーザーの追加を実現しました。この記事では、主にフロントエンドとバックエンドのユーザーリストページ検索、ファジークエリ、ユーザーリストレンダリング機能の実現について説明します。
- 1つ目はページング検索です。バックエンドの実装方法では、データベースの長さを使用してテーブルを検索します。データベース関数skip(n)(最初のn個のデータをスキップ)とlimit(m)(m個のデータを逆方向に検索)を使用してdb.findを実行します。 ()((ページ1)*のpageSize).limit(pageSizeを).SKIP(ページ0から出発して、ページの数を表し、最初のページはスキップする必要はない。pageSizeをページングした後にページごとのデータ項目の数を表す。)、そうcommand.jsに、テーブルの長さを照会するための2つの新しいメソッドと、キーワードの照会とページネーションを作成します。
/* 查询分页
* @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: "查找成功",
});
});
バックエンド部分の実装後、フロントエンドの作成を開始します。フォームコンポーネント、ページングコンポーネント、入力検索コンポーネントを使用する必要があります。ここで、フォームコンポーネントを個別に作成し、後の製品リストで再利用するための独自のコンポーネントとして作成できます。
- 最初にユーザーフォームフィールドを構成し、それらをクラスにカプセル化します
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>;
},
},
{
align: "center",
title: "密码",
dataIndex: "password",
width: 300,
},
{
align: "center",
title: "头像",
dataIndex: "headPic",
width: 150,
render: (imgPath) => {
return (
<img
src={FilePath + imgPath}
alt=""
style={
{ width: 60, margin: "0 auto" }}
/>
);
},
},
{
align: "center",
title: "性别",
dataIndex: "sex",
width: 200,
render: (sex) => {
return <div>{sex == "man" ? "男" : "女"}</div>;
},
},
{
align: "center",
title: "收货地址",
dataIndex: "alladdress",
width: 200,
render: (text, data, index) => {
return <div>{text.join("-") + data.address}</div>;
},
},
{
align: "center",
title: "个性签名",
dataIndex: "descript",
width: 200,
},
{
align: "center",
title: "用户类型",
dataIndex: "userType",
width: 200,
render: (type) => {
return <div>{type == "admin" ? "管理员" : "用户"}</div>;
},
},
{
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 (
<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);
};
}
- 最後に、テーブル内のページでデータの双方向バインディング効果を実現するために、ユーザーリストで呼び出されます。
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) => {});
};
}
- すべてが終わったら、それをテストします
総括する
フロントエンドコードのコンポーネントベースの開発では、コンポーネントの再利用によりコードの保守性を向上させることができます。対応するコンポーネントを使用するように状態または初期状態値を変更することにより、コードの効率が大幅に向上します。