有些人写的文章叫做教程
有些人写的文章叫做科普
而我写的文章多半是篇水贴
当然如果你的项目中允许你直接使用 antd 的组件,那是很舒服,无论是 3.0 的Form.create()或者 4.0 的no create ,额,好吧,我可能是一个比较遵循官方写法的简单用户,我就从来没有发现Form有什么问题。你知道的,懒得去看 issues 和文档的伸手党,发现 bug 都会当做是新特性的。
由于我们项目中使用的是 umi ,它内置了 antd 和 antd-mobile 并且都配置了按需加载,我们 UI 在设计的时候,有时候(几乎)会参考 antd 的官网,也有几个用上了高级的 kitchen,所以很多前端同事,也会偷偷的在 mobile 项目中使用 antd 的组件,这种事情,我都是当作没看到的。反正他们乐意重写一遍样式也没多大问题。
言归正传
那我就想 antd@4 的 From 能不能直接用到 mobile 里面。
import { Form } from 'antd'; // 4.0.0-rc.1 import { InputItem, Button } from 'antd-mobile'; const [form] = Form.useForm(); return ( <Form form={form} name="basic" initialValues={{ username: 'xiaohuoni' }} onFinish={onFinish} onFinishFailed={onFinishFailed} > <List> <Form.Item name="username" rules={[{ required: true, message: 'Please input your username!' }]} > <InputItem>Username</InputItem> </Form.Item> <Form.Item name="password" rules={[{ required: true, message: 'Please input your password!' }]} > <InputItem>Password</InputItem> </Form.Item> <Form.Item {...tailLayout}> <Button type="primary" onClick={() => form.submit()}> Submit </Button> </Form.Item> </List> </Form> )
竟然可以用,通过 umi-plugin-cordova 打包成了 app,在不同的设备上测试了兼容性。目前没发现什么问题(以我看不到 bug 的眼睛)。就是这个错误提示,不太像是移动端的,后面再随便改改。
rc-form
import { InputItem } from 'antd-mobile'; import React, { FC } from 'react'; import { createForm, formShape } from 'rc-form'; interface PageProps { form: formShape; } const Page:FC<PageProps> = () => { const { form } = this.props; const { getFieldProps } = form; return ( <List> <InputItem {...getFieldProps('username', { initialValue:'xiaohuoni', rules: [{ required: true, message: 'Please input your username!' }], })} > title </InputItem> </List> ); }; export default createForm()(Page);
rc-field-form
import { InputItem } from 'antd-mobile'; import React, { FC } from 'react'; import Form, { Field, useForm } from 'rc-field-form'; const Page: FC = () => { const [form] = useForm(); return ( <Form form={form} name="basic" initialValues={{ username: 'xiaohuoni' }}> <Field name="username" rules={[{ required: true, message: 'Please input your username!' }]} > <InputItem>Username</InputItem> </Field> </Form> ); }; export default Page;
(其实和直接使用antd@4 的 Form 差不多,直接用 Field 替换 Form.Item 就好)
嗯,还是挺完美的。
remax
上次See Conf 的时候, 边柳在【技术专场】使用 React 开发小程序 中有提到, rc-field-form
可以直接在 remax 上使用。回来自己试了一下,是这样子的。
import * as React from 'react'; import { View, Text, Image, Input, Button } from 'remax/wechat'; import Form, { Field, useForm } from 'rc-field-form'; import styles from './index.module.css'; export default () => { const [form] = useForm(); const onFinish = values => { console.log('Success:', values); }; const onFinishFailed = errorInfo => { console.log('Failed:', errorInfo); }; return ( <View className={styles.app}> <View className={styles.header}> <Form form={form} name="basic" initialValues={{ username: 'ssad' }} onFinish={onFinish} onFinishFailed={onFinishFailed} > <Field name="username" rules={[{ required: true, message: 'Please input your username!' }]} > <Input /> </Field> <Button onClick={() => form.submit()}>提交</Button> </Form> </View> </View> ); };
(此处应该有表情包)
带着疑问,把 remax 的文档找了一遍,都没有看到关于这一部分的说明,最后请教了边柳,才知道是在 react-component/field-form ,我的眼睛不止看不到 bug ,现在还看不到文档。
修改一下我的代码,加上了 component={false}
,终于跑通了阿。
然后,这次细心的我发现了一个问题,我在代码里面写了 initialValues={{ username: 'ssad' }} 为什么没有绑定上???对于好几年没写小程序的人来说,敲下的每一个字母都是在怀疑自己。
接着问大佬吧,给看了我的代码,嗯,大佬也觉得没什么问题,然后大佬偷偷告诉了我一个秘密。
“陈帅写的”。
和陈帅详细的比对了我俩的代码。没发现任何异常。然后我就怀疑是豆酱 "偷偷的在代码里面下毒"。然后我就在这三个男人之间,辗转反则(这词用的不太对)。
最后发现是在支付宝小程序上可以正确运行,而在微信小程序上不行。提一个bug [问题]使用 rc-field-form 在微信小程序上,无法绑定组件 https://github.com/remaxjs/remax/issues/589
然后在短短的四分钟之后,就被解答了。
React Native
其实跑通了remax,照着写rn的实现就可以了。需要注意的几点(其实在remax里面也一样,放到这里写,是因为上面都说了,这里就没得写了)。
Form 要设置 component={false}
Field 要根据组件响应的函数,设置 trigger="onInput",比如 remax 中设置的是trigger="onInput" ,React Native 中设置的是 trigger="onChangeText" ,如果你有使用其他的第三方组件库,可以留意一下表单组件的onChange 应该被正确替换成什么。
最终版本的RN 代码 如下
<Form form={form} component={false} name="basic" initialValues={{ username: '我是猪' }} onFinish={onFinish} onFinishFailed={onFinishFailed} > <Field name="username" rules={[{ required: true, message: 'Please input your username!' }]} trigger="onChangeText" > <TextInput></TextInput> </Field> <Button onPress={() => form.submit()}>提交</Button> </Form>
终于知道为什么我去年写的少了,3分钟写文章,30分钟找 bug,300分钟改 bug,Over!!
然后 rc-field-form
是一个跨平台组件,真香。
总结:嗯,总要写点总结的嘛,谁说水贴就不配有总结的。圆规请再转一次。其实现在我应该吃完午饭在午休才对的,嗯,饮水机的水免费的啊,真香。
(特别鸣谢:边柳、豆酱、期贤、16宇友情出演)