Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@
"classnames": "^2.5.1",
"lodash.isequal": "^4.5.0",
"lodash.kebabcase": "^4.1.1",
"react-transition-group": "^4.4.5"
"react-transition-group": "^4.4.5",
"rc-util": "^5.32.2"
},
"devDependencies": {
"@babel/core": "^7.23.9",
Expand Down
5 changes: 5 additions & 0 deletions src/packages/form/demo.taro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Demo4 from './demos/taro/demo4'
import Demo5 from './demos/taro/demo5'
import Demo6 from './demos/taro/demo6'
import Demo7 from './demos/taro/demo7'
import Demo8 from './demos/taro/demo8'

const FormDemo = () => {
const [translated] = useTranslate({
Expand All @@ -19,6 +20,7 @@ const FormDemo = () => {
relatedDisplay: '关联展示',
title4: 'Form.useForm 对表单数据域进行交互。',
title5: '表单类型',
title6: 'Form.useWatch 对表单数据监听',
validateTrigger: '校验触发时机',
},
'en-US': {
Expand All @@ -28,6 +30,7 @@ const FormDemo = () => {
relatedDisplay: 'Related Display',
title4: 'Interact with form data fields via Form.useForm',
title5: 'Form Type',
title6: 'Watch field data change with Form.useWatch',
validateTrigger: 'Validate Trigger',
},
})
Expand All @@ -50,6 +53,8 @@ const FormDemo = () => {
<Demo6 />
<h2>{translated.title5}</h2>
<Demo7 />
<h2>{translated.title6}</h2>
<Demo8 />
</div>
</>
)
Expand Down
5 changes: 5 additions & 0 deletions src/packages/form/demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Demo4 from './demos/h5/demo4'
import Demo5 from './demos/h5/demo5'
import Demo6 from './demos/h5/demo6'
import Demo7 from './demos/h5/demo7'
import Demo8 from './demos/h5/demo8'

const FormDemo = () => {
const [translated] = useTranslate({
Expand All @@ -17,6 +18,7 @@ const FormDemo = () => {
relatedDisplay: '关联展示',
title4: 'Form.useForm 对表单数据域进行交互。',
title5: '表单类型',
title6: 'Form.useWatch 对表单数据监听',
validateTrigger: '校验触发时机',
},
'en-US': {
Expand All @@ -26,6 +28,7 @@ const FormDemo = () => {
relatedDisplay: 'Related Display',
title4: 'Interact with form data fields via Form.useForm',
title5: 'Form Type',
title6: 'Watch field data change with Form.useWatch',
validateTrigger: 'Validate Trigger',
},
})
Expand All @@ -47,6 +50,8 @@ const FormDemo = () => {
<Demo6 />
<h2>{translated.title5}</h2>
<Demo7 />
<h2>{translated.title6}</h2>
<Demo8 />
</div>
</>
)
Expand Down
100 changes: 100 additions & 0 deletions src/packages/form/demos/h5/demo8.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React from 'react'
import { Cell, Form, Input, Picker, Radio, Toast } from '@nutui/nutui-react'
import { ArrowRight } from '@nutui/icons-react'

const Demo8 = () => {
const pickerOptions = [
{ value: 4, text: 'BeiJing' },
{ value: 1, text: 'NanJing' },
{ value: 2, text: 'WuXi' },
{ value: 8, text: 'DaQing' },
{ value: 9, text: 'SuiHua' },
{ value: 10, text: 'WeiFang' },
{ value: 12, text: 'ShiJiaZhuang' },
]
const submitFailed = (error: any) => {
Toast.show({ content: JSON.stringify(error), icon: 'fail' })
}

const submitSucceed = (values: any) => {
Toast.show({ content: JSON.stringify(values), icon: 'success' })
}

const [form] = Form.useForm()
const usernameWatch = Form.useWatch('username', form)

const noteWatch = Form.useWatch((values) => {
return values.picker
}, form)

const genderWatch = Form.useWatch((values) => {
return values.gender
}, form)

return (
<>
<Form
form={form}
onFinish={(values) => submitSucceed(values)}
onFinishFailed={(values, errors) => submitFailed(errors)}
>
<Form.Item
label="字段A"
name="username"
initialValue="默认值"
rules={[{ required: true, message: '请输入字段A' }]}
>
<Input placeholder="请输入字段A" type="text" />
</Form.Item>
<Form.Item
label="Picker"
name="picker"
trigger="onConfirm"
getValueFromEvent={(...args) => args[1]}
onClick={(event, ref: any) => {
ref.open()
}}
>
<Picker options={[pickerOptions]}>
{(value: any) => {
return (
<Cell
style={{
padding: 0,
'--nutui-cell-divider-border-bottom': '0',
}}
className="nutui-cell--clickable"
title={
value.length
? pickerOptions.filter((po) => po.value === value[0])[0]
?.text
: 'Please select'
}
extra={<ArrowRight />}
align="center"
/>
)
}}
</Picker>
</Form.Item>
<Form.Item label="字段B" name="gender">
<Radio.Group>
<Radio value="male">male</Radio>
<Radio value="female">female</Radio>
</Radio.Group>
</Form.Item>
</Form>
<Cell>
<div>字段A:{usernameWatch}</div>
</Cell>
<Cell>
<div>Picker:{noteWatch}</div>
</Cell>
<Cell>
<div>字段B:{genderWatch}</div>
</Cell>
</>
)
}

export default Demo8
101 changes: 101 additions & 0 deletions src/packages/form/demos/taro/demo8.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from 'react'
import Taro from '@tarojs/taro'
import { Cell, Form, Input, Picker, Radio } from '@nutui/nutui-react-taro'
import { ArrowRight } from '@nutui/icons-react-taro'

const Demo8 = () => {
const pickerOptions = [
{ value: 4, text: 'BeiJing' },
{ value: 1, text: 'NanJing' },
{ value: 2, text: 'WuXi' },
{ value: 8, text: 'DaQing' },
{ value: 9, text: 'SuiHua' },
{ value: 10, text: 'WeiFang' },
{ value: 12, text: 'ShiJiaZhuang' },
]
const submitFailed = (error: any) => {
Taro.showToast({ title: JSON.stringify(error), icon: 'error' })
}

const submitSucceed = (values: any) => {
Taro.showToast({ title: JSON.stringify(values), icon: 'success' })
}

const [form] = Form.useForm()
const usernameWatch = Form.useWatch('username', form)

const noteWatch = Form.useWatch((values) => {
return values.picker
}, form)

const genderWatch = Form.useWatch((values) => {
return values.gender
}, form)

return (
<>
<Form
form={form}
onFinish={(values) => submitSucceed(values)}
onFinishFailed={(values, errors) => submitFailed(errors)}
>
<Form.Item
label="字段A"
name="username"
initialValue="默认值"
rules={[{ required: true, message: '请输入字段A' }]}
>
<Input placeholder="请输入字段A" type="text" />
</Form.Item>
<Form.Item
label="Picker"
name="picker"
trigger="onConfirm"
getValueFromEvent={(...args) => args[1]}
onClick={(event, ref: any) => {
ref.open()
}}
>
<Picker options={[pickerOptions]}>
{(value: any) => {
return (
<Cell
style={{
padding: 0,
'--nutui-cell-divider-border-bottom': '0',
}}
className="nutui-cell--clickable"
title={
value.length
? pickerOptions.filter((po) => po.value === value[0])[0]
?.text
: 'Please select'
}
extra={<ArrowRight />}
align="center"
/>
)
}}
</Picker>
</Form.Item>
<Form.Item label="字段B" name="gender">
<Radio.Group>
<Radio value="male">male</Radio>
<Radio value="female">female</Radio>
</Radio.Group>
</Form.Item>
</Form>
<Cell>
<div>字段A:{usernameWatch}</div>
</Cell>
<Cell>
<div>Picker:{noteWatch}</div>
</Cell>
<Cell>
<div>字段B:{genderWatch}</div>
</Cell>
</>
)
}

export default Demo8
8 changes: 6 additions & 2 deletions src/packages/form/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,6 @@ import { Form } from '@nutui/nutui-react'

### FormInstance

Form.useForm()创建 Form 实例,用于管理所有数据状态。

| 属性 | 说明 | 类型 |
| --- | --- | --- |
| getFieldValue | 获取对应字段名的值 | `(name: NamePath) => any` |
Expand All @@ -131,6 +129,12 @@ Form.useForm()创建 Form 实例,用于管理所有数据状态。
| resetFields | 重置表单提示状态 | `() => void` |
| submit | 提交表单进行校验的方法 | `Promise` |

### Hook

Form.useForm() 创建 Form 实例,用于管理所有数据状态。

Form.useWatch() 用于直接获取 form 中字段对应的值。

Copy link

@coderabbitai coderabbitai bot Dec 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

建议补充 Hook 部分的详细说明

Hook 部分的文档需要增加以下内容:

  • useWatch 的具体使用示例
  • useWatch 的参数类型说明
  • useWatch 的返回值类型说明
  • useWatch 的常见使用场景

建议按照以下格式补充文档:

 ### Hook

 Form.useForm() 创建 Form 实例,用于管理所有数据状态。

-Form.useWatch() 用于直接获取 form 中字段对应的值。
+Form.useWatch(name: NamePath) 用于监听字段值的变化。
+
+#### 参数
+| 参数 | 说明 | 类型 | 默认值 |
+| --- | --- | --- | --- |
+| name | 字段名称 | `string \| number \| (string \| number)[]` | - |
+
+#### 返回值
+| 类型 | 说明 |
+| --- | --- |
+| any | 对应字段当前的值 |
+
+#### 示例
+```tsx
+const Demo = () => {
+  const [form] = Form.useForm();
+  const value = Form.useWatch('field', form);
+  
+  return (
+    <Form form={form}>
+      <Form.Item name="field">
+        <Input />
+      </Form.Item>
+      <div>当前值: {value}</div>
+    </Form>
+  );
+};
+```

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

文档已更新

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Niubility-SunLight 感谢你的更新,文档部分的改动已收到,辛苦了!如果后续还需要进一步补充或有其他问题,欢迎随时留言。


If you found this review helpful, would you consider giving us a shout-out on X?
Thank you for using CodeRabbit!

## 主题定制

### 样式变量
Expand Down
3 changes: 3 additions & 0 deletions src/packages/form/index.taro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Form, FormProps } from './form.taro'
import { FormItem } from '../formitem/formitem.taro'
import { FormInstance } from './types'
import { useForm } from '@/packages/form/useform.taro'
import useWatch from './useWatch.taro'

export type {
FormItemRuleWithoutValidator,
Expand All @@ -17,11 +18,13 @@ type CompoundedComponent = React.ForwardRefExoticComponent<
> & {
Item: typeof FormItem
useForm: typeof useForm
useWatch: typeof useWatch
}

const InnerForm = Form as CompoundedComponent

InnerForm.Item = FormItem
InnerForm.useForm = useForm
InnerForm.useWatch = useWatch

export default InnerForm
3 changes: 3 additions & 0 deletions src/packages/form/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Form, FormProps } from './form'
import { FormItem } from '../formitem/formitem'
import { FormInstance } from './types'
import { useForm } from '@/packages/form/useform'
import useWatch from './useWatch'

export type {
FormItemRuleWithoutValidator,
Expand All @@ -17,11 +18,13 @@ type CompoundedComponent = React.ForwardRefExoticComponent<
> & {
Item: typeof FormItem
useForm: typeof useForm
useWatch: typeof useWatch
}

const InnerForm = Form as CompoundedComponent

InnerForm.Item = FormItem
InnerForm.useForm = useForm
InnerForm.useWatch = useWatch

export default InnerForm
10 changes: 10 additions & 0 deletions src/packages/form/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface FormItemRuleWithoutValidator {

type StoreValue = any
export type NamePath = string | number
export type InternalNamePath = (string | number)[]

export interface Callbacks<Values = any> {
onValuesChange?: (values: Values) => void
Expand All @@ -30,6 +31,15 @@ export interface FormInstance<Values = any> {
validateFields: (nameList?: NamePath[]) => Promise<any[]>
}

export type InternalFormInstance = FormInstance & { _init: boolean }

export type WatchCallBack = (
allValues: Store,
namePathList: InternalNamePath[]
) => void
export interface WatchOptions<Form extends FormInstance = FormInstance> {
form?: Form
}
export interface FormFieldEntity {
onStoreChange: (type?: string) => void
getNamePath: () => NamePath
Expand Down
Loading
Loading