登录界面的核心是表单控制, 包括自定义所有的表单内容为组件, 阻止默认事件发生, 自定义表单提交的事件等等.
这里还有一个登录状态管理的问题, 留到后边再说
- 登录页
- input组件
- 按钮组件
登录页
登录页也是老套路了, 先做一个页面, 然后是两个组件用来显示表单.
在其中, 把每个登录框和按钮, 也做成一个自定义组件可以复用.
依然创建组件然后导入:
import React from "react";
import './sign-in-and-sign-up.styles.scss';
const SingInAndSignUpPage = () => (
<div className='sign-in-and-sign-up'>SIGN IN</div>
);
export default SingInAndSignUpPage;
app.js中导入然后设置路由是/signin, 这都是常规操作, 不说了.
接下来是在页面里设置组件, 第一个组件就是SIGN-IN这个表单组件:
import React from "react";
import './sign-in.styles.scss';
class SignIn extends React.Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: ''
}
}
handleSubmit = event =>{
event.preventDefault();
this.setState({email:'', password: ''})
}
handleChange = event =>{
const {value, name} = event.target;
this.setState({
[name]: value
})
}
render() {
return (
<div className='sign-in'>
<h2>I already have a account</h2>
<span>Sign in with your email and password</span>
<form onSubmit={this.handleSubmit}>
<input type="text" name='email' value = {this.state.email} onChange={this.handleChange} required/>
<label>Email</label>
<input type="password" name='password' value = {this.state.password} onChange={this.handleChange} required/>
<label>Password</label>
<input type="submit" value='Submit'/>
</form>
</div>
);
}
}
export default SignIn;
这里有两个函数,绑定在了表单提交和两个框的变化事件上, 用于将当前的state设置为输入的内容, 很显然, 之后在点击发送的时候就可以根据state的内容来发送.
input组件
接下来任务是编写一个通用的input组件, 然后只要给其传入各种参数, 就可以控制其成为普通的, email, 密码等各种格式, 一次编写好多次使用.
创建组件目录form-input和内部的文件,
import React from "react";
import './form-input.styles.scss';
const FormInput = ({handleChange, label, ...otherProps}) =>{
return (
<div className='group'>
<input className='form-input' onChange={handleChange} {...otherProps} />
{
label ?
(<label className={`${otherProps.value.length ? 'shrink' : ""} form-input-label`}>{label}</label>) : null
}
</div>
);
}
export default FormInput;
这里的关键是利用样式来作出这个效果, 还有就是根据传入的label不同, 来是否显示label. 只要不传, 就不会渲染那个浮动的label标签.
这里的样式很有意思, 将label标签固定在input框内部, 为焦点或者有输入内容的时候, 就让其浮动和变小到上边去. 学到了.
按钮组件
按钮组件需要搭配Input组件一起使用, 其关键的任务就是被按下之后, 需要将表单的内容进行提交, 由于表单组件已经设置了提交的事件, 因此就是将这个事件传递给按钮组件即可:
而且按键组件也要做成一个无状态的组件, 类似于input组件, 这样可以在各处复用.
import React from "react";
import './custom-button.styles.scss';
const CustomButton = ({children, ...otherProps}) => (
<button className='custom-button' {...otherProps}>
{children}
</button>
);
export default CustomButton;
很显然, 需要从父组件把内容传递过来, 这里不需要传递提交事件, 只需要把button设置为submit, 点击之后触发是的表单的事件, 而表单的事件是通过特殊的属性onSubmit来设置的, 所以这个button组件可以方便的在所有表单中使用.:
import CustomButton from "../custom-button/custom-button.component";
render() {
return (
<div className='sign-in'>
<h2>I already have a account</h2>
<span>Sign in with your email and password</span>
<form onSubmit={this.handleSubmit}>
<FormInput label='email' type="text" name='email' value = {this.state.email} handleChange={this.handleChange} required/>
<FormInput label='password' type="password" name='password' value = {this.state.password} handleChange={this.handleChange} required/>
<CustomButton type="submit">SIGN IN</CustomButton>
</form>
</div>
);
}
这样就完成了登录页面的编写, 下边要来使用FireBase的认证功能来完成登录功能了.