下载:axios antd-mobile antd-mobile-icons sass
连接mongodb:
const mongoose = require("mongoose") mongoose.connect('mongodb://127.0.0.1:27017/zg5_zk3_2204_express',(err)=>{ if(!err){ console.log('连接成功!'); } }) module.exports=mongoose
创建表模型:
const mongoose = require("./db") var Schema = mongoose.Schema // 图书 var bookSchema = new Schema({ bookName:String, img:String, // 判断是否在书架里: false没在书架,true在书架 state:{ type:Boolean, default:false }, // 判断是否看完:false正在看,true已完结 bookState:{ type:Boolean, default:false } }) var bookModel = mongoose.model("Book",bookSchema) // 用户 var userSchema = new Schema({ mobile:String, passWord:String }) var userModel = mongoose.model("User",userSchema) module.exports = { bookModel,userModel }
后端接口:
// 登录时添加用户 router.post("/user/add",async (req,res)=>{ var data = req.body await userModel.create(data) res.send({ token:data.mobile }) }) // shop路由及book路由图书展示 router.get("/book/list",async (req,res)=>{ var data if(!req.query.search){ data = await bookModel.find() }else{ data = await bookModel.find({bookName:req.query.search}) } res.send({ data }) }) // shop路由的图书添加 router.post("/book/add",async (req,res)=>{ let data = req.body._id await bookModel.updateOne({_id:data},{state:true}) res.send({}) }) // bookState状态的更改 router.post("/bookState/update",async (req,res)=>{ let data = req.body await bookModel.updateOne({_id:data._id},{bookState:data.bookState}) res.send({}) }) // state状态的更改 router.post("/state/update",async (req,res)=>{ let data = req.body await bookModel.updateOne({_id:data._id},{state:false}) res.send({}) })
前端登录页面:
import React, { useState } from 'react' import { Form, Input, Button } from 'antd-mobile' import styles from './demo2.less' import { CloseOutline, CheckOutline } from 'antd-mobile-icons' import { history } from 'umi' import axios from 'axios' export default function Login() { /** 切换主题 */ // 存储颜色列表 const back = ["black","red", "blue", "green"] const [backIndex, setBackIndex] = useState(0) // 切换主题 let backClick = () => { let backindex = backIndex if (backindex >= back.length - 1) { setBackIndex(0) } else { backindex += 1 setBackIndex(backindex) } } /** 手机号 */ // 存储手机号,用于校验 const [mobile, setMobile] = useState("") // 手机号的change事件 let onMobileChange = (value) => { setMobile(value) } // 手机号的校验 const phone = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/ /** 密码 */ // 存储密码,用于校验 const [passWord, setPassWord] = useState("") // 密码的change事件 let onPassWordChange = (value: any) => { setPassWord(value) } // 密码的校验 const pwd = /^[a-zA-Z][a-zA-Z0-9]{5}$/ /** 点击登录 */ let onLoginClick = () => { axios.post("http://localhost:3000/user/add", { mobile: mobile, passWord: passWord }).then(value => { window.localStorage.setItem("token", value.data.token) history.push({ pathname: "/shop" }) }) } return ( <div> <h1 style={{ height: "60px", width: "100%", color: "white", textAlign: "center", fontSize: "24px", lineHeight: "60px", backgroundColor: back[backIndex] }}>用户登录 <b onClick={backClick} style={{ fontSize: "12px", float: "right", lineHeight: "60px", color: "white" }}>切换主题</b> </h1> <div> <Form style={{ marginTop: "150px" }} layout='horizontal'> <Form.Item label='手机号码' extra={ <div className={styles.extraPart}> {phone.test(mobile) ? <CheckOutline style={{ background: "green", border: "none", borderRadius: "50%", color: "white" }} /> : <CloseOutline style={{ background: "red", border: "none", borderRadius: "50%", color: "white" }} />} </div> } > <Input onChange={onMobileChange} placeholder='请输入手机号码' clearable /> </Form.Item> <Form.Item label='密码' extra={ <div className={styles.extraPart}> {pwd.test(passWord) ? <CheckOutline style={{ background: "green", border: "none", borderRadius: "50%", color: "white" }} /> : <CloseOutline style={{ background: "red", border: "none", borderRadius: "50%", color: "white" }} />} </div> } > <Input onChange={onPassWordChange} placeholder='请输入密码' clearable /> </Form.Item> <Button onClick={onLoginClick} disabled={pwd.test(passWord) && phone.test(mobile) ? false : true} style={{ border: "none", background: back[backIndex], marginTop: "50px" }} block type='submit' color='primary' size='large'> 登录 </Button> </Form> </div> </div> ) }
css样式:scss格式
.extraPart { border-left: solid 1px #eeeeee; padding-left: 12px; font-size: 17px; line-height: 22px; } .eye { padding: 4px; cursor: pointer; svg { display: block; font-size: var(--adm-font-size-7); } }
图书商城:
import React, { useEffect, useState } from 'react' import { Input,Toast } from 'antd-mobile' import { CloseOutline, CheckOutline,AddOutline } from 'antd-mobile-icons' import axios from 'axios' import { history } from 'umi' export default function Shop() { const [inputValue,setInputValue] = useState("") const [data,setData] = useState([]) let getBookList = (value:any) =>{ axios.get("http://localhost:3000/book/list?search="+value).then(value=>{ setData(value.data.data); }) } let onInputChange = (value:any) =>{ setInputValue(value) getBookList(value) } // 添加图书到书架 let addBook = (item:any) =>{ if(item.state){ Toast.show({ content: '书架中已有此书', duration: 1000, }) }else{ axios.post("http://localhost:3000/book/add",{_id:item._id}).then(value=>{ getBookList(inputValue) Toast.show({ content: '加入成功', duration: 1000, }) }) } } useEffect(()=>{ getBookList(inputValue) },[]) return ( <div> <h1 style={{ position:"sticky",top:"0",left:"0", height: "60px", width: "100%", color: "white", textAlign: "center", fontSize: "24px", lineHeight: "60px", backgroundColor: "red" }}>图书商城 <b onClick={() => { history.push({pathname:"/book"}) }} style={{ fontSize: "12px", float: "right", lineHeight: "60px", color: "white" }}>我的书架</b> </h1> <div> <Input onChange={onInputChange} style={{ border:"1px solid red",marginTop:"-5px" }} placeholder='请输入书名搜索' /> <div> { data.map((item, index) => { return (<div key={item.bookName} style={{ marginBottom:"5px",border:"1px solid black", float: index%2==0 ? "left":"right", width: "45%", display: "inline-block" }}> <img style={{ marginBottom:"15px",height:"200px",width: "100%" }} src={require("../images/" + item.img)} alt="" /> <p style={{ color:'red' }}>{item.bookName} <AddOutline onClick={()=>{addBook(item)}} style={{ float:"right",marginRight:"10px", color:"white",backgroundColor:"red",border:"none",borderRadius:"50%" }} /></p> </div>) }) } </div> </div> </div> ) }
书架:
import React, { useState, useEffect } from 'react' import { NavBar, Collapse } from 'antd-mobile' import axios from 'axios' import { history } from 'umi' export default function Book() { const [data, setData] = useState([]) const back = () => { history.push({pathname:"/shop"}) } useEffect(() => { axios.get("http://localhost:3000/book/list").then(value => { setData(value.data.data); }) }, []) let onLeftClick = (id, state) => { axios.post("http://localhost:3000/bookState/update", { _id: id, bookState: state }).then(value => { axios.get("http://localhost:3000/book/list").then(value => { setData(value.data.data); }) }) } let onRightClick = (id) => { axios.post("http://localhost:3000/state/update", { _id: id }).then(value => { axios.get("http://localhost:3000/book/list").then(value => { setData(value.data.data); }) }) } return ( <div> <NavBar style={{ color: "white", textAlign: "center", fontSize: "24px", lineHeight: "60px", backgroundColor: "red" }} onBack={back}>图书商城 </NavBar> <div> <Collapse> <Collapse.Panel key='1' title='正在看'> <ul style={{ listStyle: "none" }}> { data.filter(item => { return !item.bookState && item.state }).length >0? data.filter(item => { return !item.bookState && item.state }).map(item => { return ( <li key={item.bookName} style={{ marginBottom: "7px" }}> <b style={{ color: "black" }}>{item.bookName}</b> <div style={{ float: "right" }}> <span onClick={() => { onLeftClick(item._id, true) }} style={{ color: "red" }}>标记为已看完 |</span> <span onClick={() => { onRightClick(item._id) }}> 删除图书</span> </div> </li> ) }): <li>没有正在看的图书</li> } </ul> </Collapse.Panel> <Collapse.Panel key='2' title='已完结'> <ul style={{ listStyle: "none" }}> { data.filter(item => { return item.bookState && item.state }).length >0? data.filter(item => { return item.bookState && item.state }).map(item => { return ( <li key={item.bookName} style={{ marginBottom: "7px" }}> <b style={{ color: "black" }}>{item.bookName}</b> <div style={{ float: "right" }}> <span onClick={() => { onLeftClick(item._id, false) }} style={{ color: "red" }}>再看一遍 |</span> <span onClick={() => { onRightClick(item._id) }}> 删除图书</span> </div> </li> ) }): <li>没有看完的图书</li> } </ul> </Collapse.Panel> </Collapse> </div> </div> ) }
标签:axios,value,react,item,商城,import,data,id,图书 From: https://www.cnblogs.com/wananyy/p/17595825.html