git命令步骤
程序员A
git init
git add .
git commit -m "init app"
git remote add origin https://gitee.com/远程仓库地址.git
git push origin master
git checkout -b dev
git push origin dev
程序员B
git clone https://gitee.com/远程仓库地址.git
git checkout -b dev origin/dev
git branch
git pull origin dev
其实克隆时已经把项目的所有分支拉取到本地,只是本地没创建dev分支。所以要根据远程的dev分支,创建本地的dev分支。
基本结构
引入antd
自定义主题
react全家桶的视频使用antd 3.x的方式按需引入和自定义主题,除了less-loader版本要降低,其它顺利完成。该方法不再需要引入antd.css文件 这次按照antd 4.x的官方文档,不需要配置按需引入,但要在index.js中引入antd样式文件import 'antd/dist/antd.less' 。
但定义主题遇到问题:
解决办法:文章链接 npm i --legacy-peer-deps @craco/craco,这种方式解决依赖冲突,不会覆盖已有的 npm i --legacy-peer-deps craco-less 其他文章 不知道有什么后果,但还是实现了
引入路由
映射路由(注册路由),这个概念忘光了。。。
最大问题是,react-router-dom v6 与 v5(之前学的)变化很大,可以根据博客修改。张天禹老师P127-P141 也更新的v6的讲解视频,我还是先去学。然后项目还是先降低版本(“react-router-dom”: “^5.3.0”),除非不能用。
v6版本的变化,确实修改之后可以用,但使用v6当前水平无法继续进行了。
<BrowserRouter>
<Switch>
<Route path='/login' component={Login}></Route>
<Route path='/' component={Admin}></Route>
</Switch>
</BrowserRouter>
Login路由组件
注意1: 一开始没有标签,所以高度为0,需在reset.css设置最大盒子的宽高
注意2: 在less样式文件中可以相对路径形式引入图片 background-image: url('./images/bg.jpg'); 而在jsx的标签里面不允许,正确操作是:先加载图片模块,logo是个动态的变量,再赋给标签属性
import logo from './images/logo.png'
<img src={logo} alt="logo" />
注意3: display:flex——Flex布局没学,菜鸟教程,迅速入门
采用Flex布局的元素,称为Flex容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称”项目”。设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。所以涉及 容器的属性 和 项目的属性。
antd—Form表单
antd登录框
antd3.x 和 4.x还是很大不同,所以一定以文档为准
- 表单提交事件不同
<Form name="normal_login" className="login-form" initialValues={{remember: true,}} onFinish={onFinish}>
- Icon图标不同.
import {Icon} from 'antd'
import { UserOutlined} from '@ant-design/icons';
<Input prefix={<UserOutlined className="site-form-item-icon" />} placeholder="Username" />
prefix:带有前缀图标的 input,属性值为ReactNode(即标签结构)
前台表单验证、收集数据
- 获取数据方式不同
3.x版本: 先要包装Login组件,向里面的Form组件传一个对象,this.props.form接收到。form这个对象里面有很多方法,其中就可以获取到表单数据。 4.x版本 Form组件的onFinish属性接收事件处理函数,调用函数自动传表单数据values,而且不会触发表单提交(页面刷新)
onFinish = (values) => {
console.log('Received values of form: ', values);
};
扩展:3.x 高阶组件 Form.create()就是高阶组件。注意:这叫组件标签,是组件的实例化。class login extends Component 这个才叫组件。
扩展:4.x 与表单数据交互
我们推荐使用 Form.useForm 创建表单数据域进行控制。如果是在 class component 下,你也可以通过 ref 获取数据域。
formRef = React.createRef();
<Form ref={this.formRef} name="normal_login" onFinish={this.onFinish}>
onFill = () => {
this.formRef.current.setFieldsValue({
username: 'admin',
password: '123456',
});
};
当然,表单都是通过标识名称找到数据。
表单验证
分为 输入完验证(声明式验证、自定义验证) 和 提交前验证
Form.Item属性 解决:
FormInstance
根据内置验证规则进行声明式验证,为rules={[ ,,]}添加对象元素 自定义表单校验规则:
rules={[
{
validator: (_, value) =>
value ? Promise.resolve() : Promise.reject(new Error('Should accept agreement')),
},
]}
提交前验证 所以不需要在onFinish回调函数验证表单,validateFields返回示例
onFinish = (values) => {
this.formRef.current.validateFields().then(values => {
const { username, password } = values
console.log('提交登陆请求', username, password);
}).catch(error => {
console.log(error.errorFields)
})
};
而3.x 版本的提交事件,需要自己写验证:
目前login路由组件代码
感谢网友先完成了4.x版本的代码,起码有参考
import React, { Component } from 'react'
import { Form, Input, Button } from 'antd';
import { UserOutlined, LockOutlined } from '@ant-design/icons';
import './login.less'
import logo from './images/logo.png'
const Item = Form.Item
export default class login extends Component {
formRef = React.createRef();
validator = (rule, value) => {
const pwdReg = /^[a-zA-Z0-9_]+$/
if (!value) {
return Promise.reject("Please input your Username")
} else if (!pwdReg.test(value)) {
return Promise.reject("has illegal chars")
} else if (value.length < 5) {
return Promise.reject("no less than 5 chars")
} else if (value.length > 12) {
return Promise.reject("no more than 12 chars")
} else {
return Promise.resolve()
}
}
onFinish = (values) => {
const { username, password } = values;
console.log('提交登陆请求', username, password);
};
onFinishFailed = (values, errorFields, outOfDate) => {
values.errorFields.map((x) => {
return console.log(x.errors);
});
};
onReset = () => {
this.formRef.current.resetFields();
};
onFill = () => {
this.formRef.current.setFieldsValue({
username: 'admin',
password: '123456',
});
};
render() {
return (
<div className="login">
<header className="login-header">
<img src={logo} alt="logo" />
<h1>React项目: 后台管理系统</h1>
</header>
<section className="login-content">
<h3>用户登录</h3>
<Form
name="normal_login"
className="login-form"
initialValues={{
remember: true,
}}
onFinish={this.onFinish}
onFinishFailed={this.onFinishFailed}
ref={this.formRef}
>
<Item
name="username"
rules={[
{ required: true, message: 'Please input your Username!' },
{ pattern: /^[a-zA-Z0-9_]+$/, message: 'has illegal chars' },
{ min: 5, message: 'no less than 5 chars' },
{ max: 12, message: 'no more than 12 chars' },
]}
validateFirst="false"
>
<Input prefix={<UserOutlined className="site-form-item-icon" />} placeholder="Username" />
</Item>
<Form.Item
name="password"
rules={[
{ validator: this.validator }
]}
>
<Input
prefix={<LockOutlined className="site-form-item-icon" />}
type="password"
placeholder="Password"
/>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" className="login-form-button">
Log in
</Button>
<Button htmlType="button" onClick={this.onReset}>
Reset
</Button>
<Button type="link" htmlType="button" onClick={this.onFill}>
Fill form
</Button>
</Form.Item>
</Form>
</section>
</div>
)
}
}
|