ゼロから、簡単なショッピングプラットフォームを構築します(5):https://blog.csdn.net/time_____/article/details/105437534
プロジェクトのソースコード(継続的な更新):https://gitee.com/DieHunter/myCode/ツリー/マスター/ショッピング
で第四の記事、サーバー側のファイルのアップロードおよび追加のユーザーのためのバックエンド機能が実装され、テストされた。この記事では主にフロントエンドのアップロードアバターとユーザーの追加を実装しています。
まず、ファイルアップロードコンポーネントをantdに導入し、コンポーネントにカプセル化します
- ユーザーがアップロードできる画像は1つだけに制限されています。アップロードコンポーネントのアクションは、4番目の記事でテストしたアップロードファイルのアドレスであるアップロードパスを表します。名前はファイル識別名、データは渡されたパラメーターです。使用済みトークン
import React from "react";
import { Upload, message } from "antd";
import { PlusOutlined } from "@ant-design/icons";
import config from "../../config/config";
let {
UploadName,
Agreement,
BaseUrl,
ServerPort,
Path,
UploadKey,
StorageName,
} = config;
export default class UpdataPic extends React.Component {
state = {
fileList: [],
};
handleChange = ({ fileList, file }) => {
this.setState({ fileList });
if (file["response"] && file.status == "done") {
let res = file["response"];
message.success(res.msg);
}
if (file["status"] == "removed") {
}
};
render() {
const { fileList } = this.state;
const uploadButton = (
<div>
<PlusOutlined />
<div className="ant-upload-text">上传头像</div>
</div>
);
return (
<div className="clearfix">
<Upload
action={Agreement + BaseUrl + ServerPort + Path + UploadName.headPic}
name={UploadKey.headKey}
listType="picture-card"
fileList={fileList}
onChange={this.handleChange}
data={
{ token: this.$utils.getStorage(StorageName.token) }}
>
{fileList.length >= 1 ? null : uploadButton}
</Upload>
</div>
);
}
}
- 次に、ページにコンポーネントを紹介して効果を試します
アップロード機能の実装後、ユーザーの追加を開始できます
- 新しいユーザーを追加するには、右側のドロワーコンポーネント、つまりDrawerコンポーネントに配置し、フォームをドロワーに埋め込みます(ユーザーの変更と新しいユーザーの追加は似ていますが、新しく追加されたユーザーDrawerでユーザー情報を直接変更しますフォームに初期値を指定するだけです)
- 注意すべき点がいくつかあります。1.antdのフォームはReact.createRef()を使用してコンポーネントをロードする必要があります。2.フォームデータに初期値を割り当てる場合、フォームのthis.formRef.current.setFieldsValue()メソッドを調整する必要があります。ただし、落とし穴があります。Drawerコンポーネントが表示されている場合、フォームコンポーネントはまだロードされていません。この時点で値を直接割り当てると、非同期のため、割り当ては失敗します。解決策(公式の処理方法はreduxグローバル管理を使用することです。ここではライフサイクル関数を使用して解決します):最初にDrawerコンポーネントでプリロード機能を有効にします(forceRender、Drawerの要素を事前レンダリングします)。)、ライフサイクルの状態の値(componentDidUpdate )を取得し、this.formRef.current.setFieldsValue()を呼び出します(ユーザー情報の変更と同じ)
import React from "react";
import Mail from "../../config/mail";
import {
Drawer,
Form,
Button,
Col,
Row,
Input,
Select,
Radio,
Cascader,
message,
} from "antd";
import config from "../../config/config";
import City from "../../config/city";
import UpdataPic from "../updata/updata";
const { ServerApi, StorageName, FilePath } = config;
const { Option } = Select;
export default class ListDrower extends React.Component {
formRef = React.createRef();
state = {
visible: false,
record: {},
};
componentDidMount() {
this.props.onDrowerRef(this);
}
componentDidUpdate() {
this.formRef.current.setFieldsValue(this.state.record);
}
showDrawer = () => {//显示Drawer
this.setState({
formType: "add",
visible: false,
record: {
sex: "man",
userType: "user",
mailurl: "@qq.com",
},
});
this.setState({
visible: true,
});
};
onClose = () => {//隐藏Drawer
this.formRef.current.resetFields();
this.setState({
visible: false,
record: null,
});
};
getPic = (data) => {//上传头像后刷新表单头像信息
this.formRef.current.setFieldsValue({
headPic: data.headPath,
});
};
delPic = () => {//删除头像后同时删除表单图片信息
this.formRef.current.setFieldsValue({
headPic: null,
});
};
sendData(val) {//提交用户信息
val.token = this.$utils.getStorage(StorageName.token);
let data = this.$crypto.setCrypto(val);
let _t = this;
this.$axios
.post(ServerApi.user.addUser, { crypto: data })
.then((res) => {
switch (res.result) {
case 1:
message.success(res.msg);
_t.onClose();
_t.props.getUserList();
break;
case 0:
message.warning(res.msg);
break;
default:
// message.warning(res.msg);
break;
}
})
.catch((err) => {
message.error("操作失败");
});
}
render() {
return (
<Drawer
title="新增用户"
width={720}
onClose={this.onClose}
visible={this.state.visible}
forceRender //加上预加载,防止表单异步生成,导致this.formRef.current为空
bodyStyle={
{ paddingBottom: 80 }}
footer={
<div
style={
{
textAlign: "right",
}}
>
<Button onClick={this.onClose} style={
{ marginRight: 20 }}>
取消
</Button>
</div>
}
>
<Form
layout="vertical"
hideRequiredMark
ref={this.formRef}
onFinish={this.sendData.bind(this)}
>
<Row gutter={16}>
<Col span={10}>
<Form.Item name="headPic" label="头像">
<UpdataPic
onUpdateRef={(child) => {
this.updateChild = child;
}}
picTarget={this.getPic}
picDelete={this.delPic}
></UpdataPic>
</Form.Item>
</Col>
<Col span={10}>
<Form.Item
name="userType"
label="用户类型"
rules={[{ required: true, message: "请选择用户类型" }]}
>
<Radio.Group buttonStyle="solid">
<Radio.Button value="admin">管理员</Radio.Button>
<Radio.Button value="user">用户</Radio.Button>
</Radio.Group>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="username"
label="用户名"
rules={[{ required: true, message: "请输入用户名" }]}
>
<Input placeholder="请输入用户名" allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="password"
label="密码"
rules={[{ required: true, message: "请输入密码" }]}
>
<Input.Password
type="password"
placeholder="请输入密码"
allowClear
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={5}>
<Form.Item
name="sex"
label="性别"
rules={[{ required: true, message: "请选择性别" }]}
>
<Radio.Group buttonStyle="solid">
<Radio.Button value="man">男</Radio.Button>
<Radio.Button value="woman">女</Radio.Button>
</Radio.Group>
</Form.Item>
</Col>
<Col span={16}>
<Form.Item label="邮箱">
<Input.Group compact>
<Form.Item
name="mailaddress"
rules={[{ required: true, message: "请输入正确邮箱" }]}
>
<Input defaultValue="" allowClear />
</Form.Item>
<Form.Item
name="mailurl"
rules={[{ required: true, message: "请选择邮箱类型" }]}
>
<Select onChange={this.changeMail} style={
{ width: 150 }}>
{(() => {
return Mail.address.map((item) => {
return (
<Option key={item.mail} value={item.mail}>
{item.mail}
</Option>
);
});
})()}
</Select>
</Form.Item>
</Input.Group>
</Form.Item>
</Col>
</Row>
<Row gutter={20}>
<Col span={16}>
<Form.Item label="收货地址" required={false}>
<Input.Group compact>
<Form.Item
name="alladdress"
// rules={[{ required: true, message: "请选择收货地址" }]}
>
<Cascader options={City} placeholder="请选择收货地址" />
</Form.Item>
<Form.Item
name="address"
// rules={[{ required: true, message: "请填写收货地址" }]}
>
<Input placeholder="请输入详细地址" allowClear />
</Form.Item>
</Input.Group>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={24}>
<Form.Item name="descript" label="个性签名">
<Input.TextArea rows={4} placeholder="个性签名" />
</Form.Item>
</Col>
</Row>
<Form.Item>
<Button
type="primary"
htmlType="submit"
className="login-form-button"
>
提交
</Button>
</Form.Item>
</Form>
</Drawer>
);
}
}
- 最後に、サーバーに試してもらいます
総括する
Reactは、ビュー表示レイヤーに基づくdom最適化フレームワークです。そのグローバル状態管理プラグインreduxは、いくつかの共有変数をグローバル化します。これは、ネイティブウィンドウスコープでグローバル変数を定義するのと同じです。便利ですが、省略できます。場所、使用量を減らすのが最善です