Skip to content

Commit

Permalink
feat(cdk:forms): add useuseAccessorAndControl, useAccessor, useControl
Browse files Browse the repository at this point in the history
  • Loading branch information
danranVm committed Jul 13, 2022
1 parent cf302ac commit e645740
Show file tree
Hide file tree
Showing 57 changed files with 629 additions and 782 deletions.
16 changes: 7 additions & 9 deletions packages/cdk/forms/__tests__/utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
import { DOMWrapper, flushPromises, mount } from '@vue/test-utils'
import { computed, provide } from 'vue'
import { provide } from 'vue'

import { Validators } from '..'
import { FormGroup } from '../src/controls'
import { useFormGroup } from '../src/useForms'
import { FORMS_CONTROL_TOKEN, useValueAccessor, useValueControl } from '../src/utils'
import { FORMS_CONTROL_TOKEN, useAccessorAndControl, useControl } from '../src/utils'

const InputComponent = {
template: `<input :value="valueRef" @input="onInput" @blur="onBlur" />`,
props: ['value', 'control'],
template: `<input :value="accessor.value" :disabled="accessor.disabled" @input="onInput" @blur="onBlur" />`,
props: ['value', 'control', 'disabled'],
emits: ['update:value'],
setup() {
const control = useValueControl()
const accessor = useValueAccessor({ control })
const valueRef = computed(() => accessor.valueRef.value)
const { accessor } = useAccessorAndControl()
const onInput = (evt: Event) => accessor.setValue((evt.target as HTMLInputElement).value)
const onBlur = () => accessor.markAsBlurred()
return { valueRef, onInput, onBlur }
return { accessor, onInput, onBlur }
},
}

const FormComponent = {
template: `<form><slot /></form>`,
props: ['control'],
setup() {
const control = useValueControl()
const control = useControl()
provide(FORMS_CONTROL_TOKEN, control)
},
}
Expand Down
4 changes: 2 additions & 2 deletions packages/cdk/forms/demo/CustomForm.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ title:

自定以一个支持 `AbstractControl` 的表单组件。

更多实现细节,请参考:[IxForm](https://github.com/IDuxFE/idux/blob/main/packages/components/form/src/Form.tsx)[IxFormItem](https://github.com/IDuxFE/idux/blob/main/packages/components/form/src/FormItem.tsx)
更多实现细节,请参考:[Form](https://github.com/IDuxFE/idux/blob/main/packages/components/form/src/Form.tsx)[FormItem](https://github.com/IDuxFE/idux/blob/main/packages/components/form/src/FormItem.tsx)

## en

Customize with a form component that supports `AbstractControl`.

For more implementation details, see: [IxForm](https://github.com/IDuxFE/idux/blob/main/packages/components/form/src/Form.tsx) and [IxFormItem](https://github.com/IDuxFE/idux/blob/main/packages/components/form/src/FormItem.tsx).
For more implementation details, see: [Form](https://github.com/IDuxFE/idux/blob/main/packages/components/form/src/Form.tsx) and [FormItem](https://github.com/IDuxFE/idux/blob/main/packages/components/form/src/FormItem.tsx).
10 changes: 5 additions & 5 deletions packages/cdk/forms/demo/CustomForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
<script setup lang="ts">
import { provide } from 'vue'
import { FORMS_CONTROL_TOKEN, useValueControl } from '@idux/cdk/forms'
import { FORMS_CONTROL_TOKEN, useControl } from '@idux/cdk/forms'
defineProps<{
control?: string | object
control?: string | number | (string | number)[] | object
}>()
// 使用 valueControl 接管 props.control 的控制
const control = useValueControl()
// 通过 props.control 拿到真正的 control(AbstractControl)
const control = useControl()
// 注入父 control, 以便子组件通过 key 获取对应的子 control
// 注入 control, 以便子组件通过 key 获取对应的子 control
provide(FORMS_CONTROL_TOKEN, control)
</script>

Expand Down
4 changes: 2 additions & 2 deletions packages/cdk/forms/demo/CustomInput.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ title:

自定义一个支持 `AbstractControl` 的输入控件。

更多实现细节,请参考:[IxInput](https://github.com/IDuxFE/idux/blob/main/packages/components/input/src/Input.tsx) 或其他输入型组件。
更多实现细节,请参考:[Input](https://github.com/IDuxFE/idux/blob/main/packages/components/input/src/Input.tsx) 或其他输入型组件。

## en

Customize with an input control that supports `AbstractControl`.

For more implementation details, see: [IxForm](https://github.com/IDuxFE/idux/blob/main/packages/components/form/src/Form.tsx) or other input components.
For more implementation details, see: [Input](https://github.com/IDuxFE/idux/blob/main/packages/components/form/src/Input.tsx) or other input components.
20 changes: 7 additions & 13 deletions packages/cdk/forms/demo/CustomInput.vue
Original file line number Diff line number Diff line change
@@ -1,30 +1,24 @@
<template>
<input class="custom-input" :value="valueRef" :disabled="isDisabled" @blur="onBlur" @input="onInput" />
<input class="custom-input" :value="accessor.value" :disabled="accessor.disabled" @blur="onBlur" @input="onInput" />
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { useValueAccessor, useValueControl } from '@idux/cdk/forms'
import { useAccessorAndControl } from '@idux/cdk/forms'
defineProps<{
value?: string
control?: string | object
control?: string | number | (string | number)[] | object
disabled?: boolean
value?: string
}>()
// 使用 valueAccessor 接管 props.value 的控制
const control = useValueControl()
const accessor = useValueAccessor({ control })
// useAccessorAndControl 内部对 props 中的 control, disabled, value 进行了处理
const { accessor } = useAccessorAndControl()
// 表单绑定的值
const valueRef = computed(() => accessor.valueRef.value)
// 表单禁用状态
const isDisabled = computed(() => accessor.disabled.value)
// 表单 blur 状态
const onBlur = () => {
accessor.markAsBlurred()
}
// 表单值发生变更后的回调
const onInput = (evt: Event) => {
const { value } = evt.target as HTMLInputElement
Expand Down
64 changes: 26 additions & 38 deletions packages/cdk/forms/docs/Index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,70 +115,58 @@ export function useFormControl<T>(

更多默认的提示信息,参见 [messages](https://github.com/IDuxFE/idux/tree/main/packages/cdk/forms/src/messages)

### useValueControl
### useAccessorAndControl

> 创建 AbstractControl,会通过 inject 从父组件中获取。
> 构建 `accessor`, 来接管表单控件 `props``control``value`, `disabled` 状态的优先级关系。
>`control` 存在时,`value``disabled` 无效,以 `control` 的状态为准。

```ts
export function useValueControl<T>(options?: ValueControlOptions): ShallowRef<AbstractControl<T> | undefined>
export interface ValueControlOptions {
/**
* 通过 props 获取 control 的 key
*/
controlKey?: string
export function useAccessorAndControl<T = any>(options?: FormAccessorOptions): {
accessor: FormAccessor<T>;
control: ShallowRef<AbstractControl<T> | undefined>;
}
```

### useValueAccessor
> 创建 ValueAccessor,用户处理 props`value``control` 的优先级关系。
export function useAccessor<T = any>(control: ShallowRef<AbstractControl<T> | undefined>, valueKey?: string, disabledKey?: string): FormAccessor<T>
```ts
export function useValueAccessor<T>(options: ValueAccessorOptions): ValueAccessor<T>
export function useControl<T = any>(controlKey?: string): ShallowRef<AbstractControl<T> | undefined>
export interface ValueAccessorOptions<T> {
export interface FormAccessorOptions {
/**
* 通过 props 获取 control 的 key
* props 中 control 的 key
*
* @default 'control'
*/
control: ShallowRef<AbstractControl<T> | undefined>
controlKey: string
/**
* 通过 props 获取 value 的 key
* props 中 value 的 key
*
* @default 'value'
*/
valueKey?: string
/**
* 通过 props 获取 disabled 的 key
* props 中 disabled 的 key
*
* @default 'disabled'
*/
disabledKey?: string
}
export interface ValueAccessor<T> {
export interface FormAccessor<T = any> {
/**
* 响应式的控件值
* 控件的值
*/
valueRef: ComputedRef<T>
value: T
/**
* 响应式的控件禁用状态
* 禁用状态
*/
disabled: ComputedRef<boolean>
disabled: boolean
/**
* 将控件设置为失去焦点状态
* 将控件设置为 blurred 状态
*/
markAsBlurred: () => void
/**
* 修改控件的值
* 设置控件的值
*/
setValue: (value: T) => void
}
```

## FAQ

### 更多的使用示例和场景?

参见 [@idux/components/form](https://idux.site/components/form/zh)

### 更多的使用细节和文档?

参见 [@angular/forms](https://angular.cn/guide/forms-overview)
Loading

0 comments on commit e645740

Please sign in to comment.