您现在的位置是:网站首页> 编程资料编程资料

react电商商品列表的实现流程详解_React_

2023-05-24 396人已围观

简介 react电商商品列表的实现流程详解_React_

整体页面效果

项目技术点

  • 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 ( <>       ) } } ]; 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); } }  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) } } 
 

分页与搜索

我们在获取数据的时候,就获取我们的分页条数和总数以及搜索的关键字,然后在分页中进行数据属性的配置即可

 // 搜索 let [search, setSearch] = useState("") // 总条数 let [total, setTotal] = useState(0) // 当前页 let [page, setPage] = useState(1) // 每页条数 let [pageSize, setPageSize] = useState(2) // 搜索 const onSearch = (val) => { setSearch(val) } // 分页 const onChange = (page, pageSize) => { setPage(page) setPageSize(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); } }  `Total ${total} items`} onChange={onChange} />

修改商品

我们在点击修改弹出对话框的同时,需要把数据绑定到输入框内,我们利用formRef.current.setFieldsValue进行数据回填,然后请求修改接口即可

 // 修改弹出框 const [isModalVisible, setIsModalVisible] = useState(false); // 修改弹出框,数据回填 const showedit = async (e) => { setIsModalVisible(true); setgoodid(e) let { data } = await axios.get(`goods/${e}`) console.log(data); formRef.current.setFieldsValue({ goods_name: data.goods_name, goods_price: data.goods_price, goods_number: data.goods_number, goods_weight: data.goods_weight }) }; // 修改取消按钮 const editHandleCancel = () => { setIsModalVisible(false) } // 修改商品 const onFinish = async (values) => { let { meta } = await axios.put(`goods/${goodid}`, { goods_name: values.goods_name, goods_number: values.goods_number, goods_price: values.goods_price, goods_weight: values.goods_weight }) // console.log(data); if (meta.status === 200) { message.success(meta.msg) setIsModalVisible(false); getUserData() } else { message.info(meta.msg) setIsModalVisible(false); } };  {/* 修改弹出框 */} 
 

删除商品

点击删除按钮传递一个id,然后请求删除接口即可

 // 删除 const delGoods = async (e) => { console.log(e); let { meta } = await axios.delete(`goods/${e}`) switch (meta.status) { case 200: message.success(meta.msg) break; default: message.warning("删除失败") break; } getUserData() } 

完整代码

import { DeleteOutlined, EditOutlined } from '@ant-design/icons'; import { Button, Card, Form, Input, message, Modal, Pagination, Table, Upload } from 'antd'; import React, { useEffect, useRef, useState } from 'react'; import axios from '../utils/request'; import './goods.scss'; const { Search } = Input; const props = { name: 'file', action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76', headers: { authorization: 'authorization-text', } } export default function Goods() { let formRef = useRef() let addFormRef = useRef(null) const [userData, setUserData] = useState([]) // 添加弹窗状态 const [addIsModalVisible, setAddIsModalVisible] = useState(false); // 存图片 let [img,setimg] = useState(""); // 搜索 let [search, setSearch] = useState("") // 总条数 let [total, setTotal] = useState(0) // 当前页 let [page, setPage] = useState(1) // 修改弹出框 const [isModalVisible, setIsModalVisible] = useState(false); // 每页条数 let [pageSize, setPageSize] = useState(2) const [goodid, setgoodid] = useState(0) const showModal = () => { setAddIsModalVisible(tru