目录
整体页面效果
项目技术点
- antd组件库,@ant-design/icons antd的图标库
- axios 接口请求,拦截器配置
- node-sass sass-loader css样式的一个嵌套
- react-router-dom react路由使用
- react-redux redux
- hooks:大多数我们用的是函数组件,函数组件没有state属性,所以我们使用hooks来初始化数据,并且函数组件没有生命周期
拦截器的配置
由于我们登录成功之后,需要我们获取到token令牌之后,我们才能获取到数据,如果每个页面都需要获取一次token,代码比较啰嗦,所以我们配置了一个拦截器
需要授权的 API ,必须在请求头中使用 Authorization
字段提供 token
令牌
//配置拦截器
import axios from "axios";
//2. 创建对象
const Server = axios.create({
baseURL:"http://api.xiaohuihui0728.cn:8888/api/private/v1/",//基地址
timeout:5000,
})
//3. 请求拦截器
Server.interceptors.request.use((config)=>{
//前置拦截器请求发送出去之前触发
console.log(config);
//增加一个token值
let token = sessionStorage.getItem("token");
config.headers["Authorization"] = token;
return config;
},(err)=>Promise.reject(err));
//4. 响应拦截器
Server.interceptors.response.use((response)=>{
//请求成功,服务端返回数据到客户端之前触发
return response.data;
},(err)=>Promise.reject(err))
//5.抛出Serve对象的内容
export default Server;
主页面
我们的数据写在columns里面,在里面的dataIndex绑定我们获取到的数据
const columns = [
{
title: '商品名称',
dataIndex: 'goods_name',
key: 'username',
},
{
title: '商品价格',
dataIndex: 'goods_price',
key: 'email',
},
{
title: '商品重量',
dataIndex: 'goods_weight',
key: 'mobile',
},
{
title: '创建时间',
dataIndex: 'goods_state',
key: 'role_name',
},
{
title: '操作',
key: 'action',
render: (_, record) => {
return (
<>
<Button type="primary" size="small" onClick={() => { showedit(record.goods_id) }}> <EditOutlined /> </Button>
<Button type="primary" size="small" danger onClick={() => { delGoods(record.goods_id) }} > <DeleteOutlined /> </Button>
</>
)
}
}
];
const [userData, setUserData] = useState([])
// 初始化数据
useEffect(() => {
getUserData()
setPage(1)
}, [search, page, pageSize])
// 初始化请求数据 用户
const getUserData = async () => {
console.log(pageSize);
console.log(search);
console.log(page);
let { data } = await axios.get(`goods?pagenum=${page}&query=${search}&pagesize=${pageSize}`)
console.log(data.goods);
if (data) {
setTotal(data.total);
setUserData(data.goods);
}
}
<Table pagination={false} bordered dataSource={userData} columns={columns} rowKey={(record) => record.goods_id} />
添加商品
添加弹出对话框,添加里面有一个上传图片,我们上传的图片有一个单独的添加接口,所以我们使用action属性绑定我们要上传的路径,headres获取token,使用onChange获取图片上传的路径,然后在我们点击提交form表单数据时把图片临时地址添加成功
// 添加弹窗状态
const [addIsModalVisible, setAddIsModalVisible] = useState(false);
// 存图片
let [img,setimg] = useState("");
// 添加取消
const addHandleCancel = () => {
setAddIsModalVisible(false);
};
//获取token
let token = sessionStorage.getItem("token");
// 添加商品
const onAdd = async (value)=>{
console.log(value);
let pics = [{pic:img}];
let data= await axios.post("goods",{...value,pics})
setAddIsModalVisible(false);
getUserData()
}
//图片上传
const success = (info)=>{
if(info.file.status==="done"){
console.log(info.file.response.data.tmp_path);
setimg(info.file.response.data.tmp_path)
}
}
<Modal title="商品添加" visible={addIsModalVisible} footer={null} ref={addFormRef}>
<Form
name="basic"
labelCol={
{ span: 4 }}
wrapperCol={
{ span: 16 }}
initialValues={
{ remember: true }}
onFinish={onAdd}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<Form.Item
label="商品名称"
name="goods_name"
rules={[{ required: true, message: '请输入商品名称' }]}
>
<Input />
</Form.Item>
<For