知识点

  • 组件:Cell、Input、Button、CheckBox。
  • 验证码
  • :gloabal样式修改

    注册页面

    image.png
    首先新建 Login 文件夹,在文件夹内添加两个文件 index.jsx 和 style.module.less,我们先把注册页面的静态页面切出来,首先给 index.jsx 添加如下代码: ```javascript import React from ‘react’

import s from ‘./style.module.less’

const Login = () => { return

注册
}

export default Login

  1. 为它添加一个路由配置,打开 router/index.js 添加如下:
  2. ```javascript
  3. import Login from '@/container/Login'
  4. ...
  5. {
  6. path: "/login",
  7. component: Login
  8. }

接下来为 Login/index.jsx 添加静态页面代码:

  1. import React from 'react'
  2. import { Cell, Input, Button, Checkbox } from 'zarm'
  3. import CustomIcon from '@/components/CustomIcon'
  4. import s from './style.module.less'
  5. const Login = () => {
  6. return <div className={s.auth}>
  7. <div className={s.head} />
  8. <div className={s.tab}>
  9. <span>注册</span>
  10. </div>
  11. <div className={s.form}>
  12. <Cell icon={<CustomIcon type="zhanghao" />}>
  13. <Input
  14. clearable
  15. type="text"
  16. placeholder="请输入账号"
  17. />
  18. </Cell>
  19. <Cell icon={<CustomIcon type="mima" />}>
  20. <Input
  21. clearable
  22. type="password"
  23. placeholder="请输入密码"
  24. />
  25. </Cell>
  26. <Cell icon={<CustomIcon type="mima" />}>
  27. <Input
  28. clearable
  29. type="text"
  30. placeholder="请输入验证码"
  31. />
  32. </Cell>
  33. </div>
  34. <div className={s.operation}>
  35. <div className={s.agree}>
  36. <Checkbox />
  37. <label className="text-light">阅读并同意<a>《掘掘手札条款》</a></label>
  38. </div>
  39. <Button block theme="primary">注册</Button>
  40. </div>
  41. </div>
  42. }
  43. export default Login

上述代码中,关键部分是账号输入、密码输入、验证码输入,这三个输入框是需要获取数据作为接口的参数提交上去的。

:global修改样式

样式编写部分,要注意的一点是 :global 这个关键词。由于我们采用的是 CSS Module 的形式进行开发,也就是你在页面中声明的类名都会根据当前页面,打一个唯一的 hash 值,比如我们页面中声明的 className={s.form},最终在浏览器中显示的是这样的:
image.png
_form_kpur3_30 是已经被编译过的样式,这样做的目的是避免和别的页面的样式重名,这是目前样式管理的一个诟病,当多人参与项目开发的时候,很难做到不污染全局样式名称,除非很小心的命名样式名称。
所以经过编译之后,想要修改 .form 下的 .za-cell,如下写法,将无法修改成功:

  1. .form {
  2. .za-cell {
  3. color: red;
  4. }
  5. }

原因是,上述写法,.za-cell 会被编译加上 hash,组件库 Zarm 内的 dom 类名还是叫 za-cell,如上图所示。所以为了不加 hash,就需要这样操作:

  1. .form {
  2. :global {
  3. .za-cell {
  4. color: red;
  5. }
  6. }
  7. }

这样 .za-cell 就不会被加上 hash,如下图所示:
image.png

验证码

安装插件npm i react-captcha-code -S
在代码中引入:

  1. ...
  2. import Captcha from "react-captcha-code"
  3. ...
  4. <Input
  5. clearable
  6. type="text"
  7. placeholder="请输入验证码"
  8. onChange={(value) => setVerify(value)}
  9. />
  10. <Captcha charNum={4} />

浏览器展示如下所示:
image.png

注册逻辑

  1. ...
  2. const [username, setUsername] = useState(''); // 账号
  3. const [password, setPassword] = useState(''); // 密码
  4. const [verify, setVerify] = useState(''); // 验证码
  5. ...
  6. <Input
  7. clearable
  8. type="text"
  9. placeholder="请输入账号"
  10. onChange={(value) => setUsername(value)}
  11. />
  12. ...
  13. <Input
  14. clearable
  15. type="password"
  16. placeholder="请输入密码"
  17. onChange={(value) => setPassword(value)}
  18. />
  19. ...
  20. <Input
  21. clearable
  22. type="text"
  23. placeholder="请输入验证码"
  24. onChange={(value) => setVerify(value)}
  25. />

当输入框内容修改的时候,onChange 会被触发,接受的回调函数参数,便是变化的输入值,此时我们将其保存在声明的变量中。
我们输入的验证码是需要和验证码图片里的验证码匹配的,所以我们还需要拿到图片里的验证码,我们作如下操作:

  1. import React, { useCallback } from 'react'
  2. ...
  3. const [captcha, setCaptcha] = useState(''); // 验证码变化后存储值
  4. // 验证码变化,回调方法
  5. const handleChange = useCallback((captcha) => {
  6. console.log('captcha', captcha)
  7. setCaptcha(captcha)
  8. }, []);
  9. ...
  10. <Captcha charNum={4} onChange={handleChange} />

当验证码变化的时候,便能获取到相应的值
到此,注册需要的参数都有了,我们开始编写注册方法:

  1. import { Cell, Input, Button, Checkbox, Toast } from 'zarm'
  2. import { post } from '@/utils'
  3. ...
  4. const onSubmit = async () => {
  5. if (!username) {
  6. Toast.show('请输入账号')
  7. return
  8. }
  9. if (!password) {
  10. Toast.show('请输入密码')
  11. return
  12. }
  13. if (!verify) {
  14. Toast.show('请输入验证码')
  15. return
  16. };
  17. if (verify != captcha) {
  18. Toast.show('验证码错误')
  19. return
  20. };
  21. try {
  22. const { data } = await post('/api/user/register', {
  23. username,
  24. password
  25. });
  26. Toast.show('注册成功');
  27. } catch (error) {
  28. Toast.show('系统错误');
  29. }
  30. };
  31. ...
  32. <Button onClick={onSubmit} block theme="primary">注册</Button>x

上述代码中,因为我们使用的是 async await 做异步处理,所以需要通过 try catch 来捕获异步处理过程中出现的错误,如果使用 Promise 的回调函数,则无需使用 try catch,如下代码(建议使用 async await):

  1. post('/api/user/register', {
  2. username,
  3. password
  4. }).then(res => {
  5. // do something
  6. })

此时我们大致将注册功能实现了。这里我不再展开讲样式部分,因为这样会使得文章中出现过多的重复代码,不以阅读,大家尽量根据标签的类名去查找 css 样式部分。