- 解决跨域: 在src 里面加 setupProxy.js
- React 项目
git add .
git commit -m ‘xxx’
git push
安装 node
安装 git
安装: cnpm
npm install -g cnpm —registry=https://registry.npm.taobao.org
安装 : react
全局安装脚手架一次: cnpm install -g create-react-app <br /> 创建项目 create-react-app myapp<br /> 启动项目 npm start
antd插件:
$ cnpm install antd -S
axios 请求数据
$ cnpm install axios -S
json-server 模拟数据
$ cnpm install json-server -g 全局安装
!!! 出现这个报错时
If you would prefer to ignore this check, add SKIP_PREFLIGHT_CHECK=true to an .env file in your project.
That will permanently disable this message but you might encounter other issues.
在src同级下 创建 .env 然后在里面加 SKIP_PREFLIGHT_CHECK=true 就可以了
连接 仓库地址
$ git remote add origin @创建的项目地址名
解决跨域: 在src 里面加 setupProxy.js
React 项目
git add .
git commit -m ‘xxx’
git push
nodejs 安装 查看这个两个是否安装
全局安装 react 脚手架工具
$ cnpm install -g create-react-app创建项目 create-react-app myapp启动项目 npm start
npx create-react-app my-appnpx 命令,先检查局部中有没有create-react-app, 如果有, 跟上面一样创建和启动项 目 如果没有,再检查全局下有没有这个命令, 如果有, 跟上面一样创建和启动项目 如果都没有,自动局部安装 create-react-app ,然后跟上面一样创建和启动项目
这个意思是这个文件里面的东西 git不会管理 的
这个意思是资源包
antd插件
$ cnpm install antd -S
axios请求数据
$ cnpm install axios -S
json-server 模拟数据
$ cnpm install json-server -g 全局安装
axios 增删改查 get post put delet
. 全局安装脚手架一次 cnpm install -g create-react-app
- 创建项目 $ create-react-app 项目名字
- 运行 $ npm start
!!! 出现这个报错时
If you would prefer to ignore this check, add SKIP_PREFLIGHT_CHECK=true to an .env file in your project.That will permanently disable this message but you might encounter other issues.
在src同级下 创建 .env 然后在里面加 SKIP_PREFLIGHT_CHECK=true 就可以了
3.连接 仓库地址
git remote add origin git@创建的项目地址名
解决跨域: 在src 里面加 setupProxy.js
页面路由配置:
/login 登录
/DashBoard 里面最大的页面
/DashBoard {
/ 首页
/home 首页
/user-manage 用户管理
/user-manage/users 用户列表
/right-manage 权限管理
/right-manage/roles 角色列表 /right-manage/rights 权限列表
/article-manage 文章管理
/article-manage/list 文章列表 /article-manage/category 文章分类
/notfound 404页面
…..
}
基本逻辑:
1.要做判断路由拦截 是否登入 没登入就跳转到登入 登入就转到 首页
这里做三目判断 看localStorage是否有token 有进跳转到首页 没有就进不去首页<Routepath="/"render={() =>localStorage.getItem("token") ? (<DashBoard />) : (<Redirect to="/login" />)}/>
2.登入页面 背景粒子效果
这里用的时候要加背景颜色 否则看不到的 如果想设置高度百分百的时候 就要减去5import Particles from "react-particles-js";<div><Particles height={window.innerHeight - 5} /></div>
3.下载好了 antd
!!! 切记 要引入 antd 的css样式 最最外面的index.js里
import 'antd/dist/antd.css';
侧边布局
<Menu 这里面只带 onClick onClick={this.handleChangePage} />//点击 跳转路径handleChangePage = (obj) => {console.log(obj)// 高阶组件提供 这样就可以跳转了this.props.history.push(obj.key); //key路由对应的路径};import { withRouter } from "react-router";export default withRouter(SideMenu);
!!! 注意这里的写法onClick={() => {this.setState({isShow: true,})}
点击添加用户:
让模态框出现 然后判断 不能为空 验证表单 然后点击完成的时候 向数据库发一个添加的请求的 把 输入的数据添加到数据库 按个开关的按钮默认是关的 然后setState { datralist : […老数据,res.data新数据]}
// 点击按钮就会显示模态框 isShow默认是false 点击让他变成 true就会显示onClick={() => {this.setState({isShow: true,});//点击完成onOk={this.handleClick}validateFields() // 这个是验证表单 必须要输入值this.refs.form.resetFields(); // 验证完重置表单this.renderTable(values); // 这个是更新数据库 和更新渲染// 添加到数据库还有渲染axios.post(`http://localhost:5000/users`,// 这个是添加到 数据库axios.post(`http://localhost:5000/users`, {username,password,roleType,roleState: false, // 这个是那个开关 默认是关的roleName: roleArr[roleType - 1], // 这个是用来渲染那个名字的 小编...}).then((res) => {console.log(res.data);// 模态框消失// table更新 前端更新 就是给 datalist重新赋值this.setState({isShow:false , // 让模态框消失// 要先把老的数据放在这里 然后显示新的 数据直接接在后面datalist: [...this.state.datalist,res.data]})});
删除
点击删除按钮 传个id过来 然后 利用请求数据 用数据的 axios.delete(这里是请求地址 ${id})的方法,然后同步后端 同步页面 同步页面就是 更新状态
// 更新状态this.setState({// 只有当删除的那个id 不相等就返回 就是相等就不返回结果datalist: this.state.datalist.filter((item) => item.id !== id),});
编辑
点击然后让 编辑那个模态框弹出来
// 这里加异步 是为了让他加载完成才 能拿到 setFieldsValue 这个预设数据setTimeout(() => {this.setState({isUpdate: true, // 模态框显示currentId: item.id, //id 记录此时要更新哪个user});// 预设数据// setFieldsValue 给表单元素提前设置数据this.refs.updataform.setFieldsValue({username: item.username,password: item.password,roleType: item.roleType,});}, 0);};
然后点击更新 先验证表单 是否合格 然后拿到表单的内容
// 更新 方法handleUpdateOk = () => {// 先验证表单this.refs.updataform.validateFields().then((values) => {console.log(values);this.updateTable(values); // 调用}).catch((err) => {console.log(err);});};// 更新 更新表格方法更新状态updateTable = (values) => {// 这个是老的状态 就是过滤当前正在点的那个id 项 这个过滤出来的是个数组let oldItems = this.state.datalist.filter((item) => item.id === this.state.currentId);let roleArr = ["小编", "管理员", "超级管理员"];// console.log(oldItems) // 是个数组格式// 更新 这里的更新是让后端更新 更新必须要有idaxios.put(`http://localhost:5000/users/${this.state.currentId}`, {// 先将老的数据 和新的数据进行合并...oldItems[0], // 老的状态 因为是个数组所以这里取第 0 项 就能拿到那个数据...values, // 新的状态 就是那个变淡输入的内容 全部在 vaules里roleName: roleArr[values.roleType - 1], // 这个是那个名字 小编...}).then((res) => {// 同步到当前页面, 这里是让前端更新let newlist = this.state.datalist.map((item) => {if (item.id === res.data.id) {// 如果找到了就把更新后的值返回出来return res.data;} else {// 没有更新的话 ,还是返回以前的return item;}});this.setState({datalist: newlist, // 更新后的数据赋值});});};
还有更新那个开关
那个开关默认是关的 可以让他开 如果是开 就可以让 那个用户登入进来 如果是关闭就不让他进来 然后更新到数据库
!!!! 注意
pagination={{ pageSize: 5 }} //这个是控制 每一页最大显示的条数
rowKey={(item) => item.id} // 这个是给每一行加id 必加的
这种属于页头 antd
这种叫步骤条
这种叫联级选择
// 这里面所需要的格式 是 label 和 value 而我们数据库的格式是 title 和value// 所以我们这里要把 label 改成 title 才能正确的显示在页面上options: [// label 级联菜单的显示内容, value 对应value值,childern],fieldNames={{ label: "title" }} //自定义 options 中 label name children 的字段
这种叫富文本编辑器
、
redux
发布 store.dispatch( { type:xxx ,payload: xxx })
订阅 store.subscribe( () => {}) 获取数据 store.getState().xxx
订阅方法 离开组件一定要取消订阅
订阅 this.unscribe= store.subscribe( () => {})// 销毁componentWillUnmount() {this.unscribe(); // 取消方法 unscribe这是个函数体 用() 销毁}
像异步请求的数据可以用这个 redux-promise
// 异步的一些操作import { createStore, applyMiddleware } from "redux";import reduxPromise from "redux-promise"; // 这个是转 promise形式的const store = createStore(reducer,{ // 默认的参数isCollapsed: false, // 初始化状态roles: [], // 初始化状态rights: [], // 初始化状态},applyMiddleware(reduxPromise));
使用这个方法可以在浏览器使用插件
import { createStore, applyMiddleware, compose } from "redux";import reduxPromise from "redux-promise"; // 这个是转 promise形式的const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; //const store = createStore(reducer,{isCollapsed: false, // 初始化状态roles: [], // 初始化状态rights: [], // 初始化状态},composeEnhancers(applyMiddleware(reduxPromise)));
react-redux
connect 连接export default connect(mapStateToProps,mapDispatchToProps)(Rights);mapStateToProps 第一个参数 相当于订阅 // connect 拿到了 store.getState() // state 这个是获取的状态 store.getState()// 第一个参数cosnt mapStateToProps = (state) => {// state 这个是获取的状态 store.getState()return { // 返回的是状态a:1,isCollapsed: state.isCollapsed,}}mapDispatchToProps 第二个参数 相当于发布const mapDispatchToProps = ({change(obj) {console.log("change-connect约定好,传给topheader的回调",obj)return obj}})
跳转到 github
<ahref="https://github.com/lichangxiong-yan/houtai"target="_blank"rel="noopener noreferrer">
图表插件 // 转格式
// 转格式// ES5componentDidMount() {// console.log(this.refs.myechart.clientWidth);axios.get("http://localhost:5000/articles").then((res) => {// console.log(res.data);// 后端给的数据不是前端想要的 ,数据转换// lodashconsole.log(_.groupBy(res.data, "author")); // 按 author 来分组// console.log(_.groupBy(res.data, (item) => item.category[0]));this.group = _.groupBy(res.data, "author");// ES5// console.log(Object.keys(this.group)); // 拿到对象中的key// console.log(Object.values(this.group).map((item) => item.length)); // 拿到对象中的每一个value值this.initEChart();});
跨域处理
路由配置
react-redux
