connect
Description
Adapter helper that wires third-party Vue components into Formily without touching their internals.
Signature
ts
import type { VueComponentProps } from '@silver-formily/vue'
interface IComponentMapper<T extends Vue.Component> {
(target: T): Vue.Component
}
declare function connect<T extends Vue.Component, Props = VueComponentProps<T>>(
target: T,
...args: IComponentMapper<T>[]
): ConnectedComponent<T, Props>Pass the component you want to enhance as the first argument, then any number of mappers. In most cases you combine it with mapProps and mapReadPretty.
By default, connect extracts the target component's public props and preserves its props, slots, and instance type. To add Formily or application-specific props, provide the second type parameter:
ts
import type { VueComponentProps } from '@silver-formily/vue'
import { connect, mapProps } from '@silver-formily/vue'
import { ElInput } from 'element-plus'
type InputProps = VueComponentProps<typeof ElInput> & {
formilyReadonly?: boolean
}
const ConnectedInput = connect<typeof ElInput, InputProps>(
ElInput,
mapProps({
formilyReadonly: 'readonly',
}),
)This only changes TypeScript inference. The runtime behavior of connect and mapProps, including attrs and event forwarding, remains unchanged.
Example
<script setup lang="ts">
import type { Field as TypeField } from '@silver-formily/core'
import { createForm, setValidateLanguage } from '@silver-formily/core'
import {
connect,
Field,
FormConsumer,
FormProvider,
mapProps,
} from '@silver-formily/vue'
import { ElButton, ElFormItem, ElInput } from 'element-plus'
setValidateLanguage('en')
const FormItem = connect(
ElFormItem,
mapProps(
{
title: 'label',
description: 'extra',
required: true,
validateStatus: true,
},
(props, field: TypeField) => ({
...props,
help: field.selfErrors?.length ? field.selfErrors : undefined,
}),
),
)
const form = createForm({ validateFirst: true })
function log(...args: unknown[]) {
console.log(...args)
}
function handleSubmit() {
form.submit(log)
}
</script>
<template>
<FormProvider :form="form">
<Form layout="vertical">
<Field
name="name"
title="Name"
required
:decorator="[FormItem]"
:component="[ElInput, { placeholder: 'Please ElInput' }]"
/>
<FormConsumer>
<template #default="{ form: _form }">
<div style="white-space: pre; margin-bottom: 16px">
{{ JSON.stringify(_form.values, null, 2) }}
</div>
<ElButton type="primary" @click="handleSubmit">
Submit
</ElButton>
</template>
</FormConsumer>
</Form>
</FormProvider>
</template><script setup lang="ts">
import type { Field as TypeField } from '@silver-formily/core'
import { createForm, setValidateLanguage } from '@silver-formily/core'
import {
connect,
Field,
FormConsumer,
FormProvider,
mapProps,
} from '@silver-formily/vue'
import { ElButton, ElFormItem, ElInput } from 'element-plus'
setValidateLanguage('en')
const FormItem = connect(
ElFormItem,
mapProps(
{
title: 'label',
description: 'extra',
required: true,
validateStatus: true,
},
(props, field: TypeField) => ({
...props,
help: field.selfErrors?.length ? field.selfErrors : undefined,
}),
),
)
const form = createForm({ validateFirst: true })
function log(...args: unknown[]) {
console.log(...args)
}
function handleSubmit() {
form.submit(log)
}
</script>
<template>
<FormProvider :form="form">
<Form layout="vertical">
<Field
name="name"
title="Name"
required
:decorator="[FormItem]"
:component="[ElInput, { placeholder: 'Please ElInput' }]"
/>
<FormConsumer>
<template #default="{ form: _form }">
<div style="white-space: pre; margin-bottom: 16px">
{{ JSON.stringify(_form.values, null, 2) }}
</div>
<ElButton type="primary" @click="handleSubmit">
Submit
</ElButton>
</template>
</FormConsumer>
</Form>
</FormProvider>
</template>
查看源码