ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Vant 中 useCustomFieldValue 使用指南:为 Form 自定义表单项注入值

Vant 中 useCustomFieldValue 使用指南:为 Form 自定义表单项注入值 Vant 中 useCustomFieldValue 使用指南为 Form 自定义表单项注入值【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant本指南围绕 Vant 移动端组件库提供的useCustomFieldValue组合式函数讲解如何在 van-field 的input插槽中插入自定义组件并让该组件的值参与 Form 的取值与校验流程。读完本文你将掌握自定义表单项的完整写法、其基于 provide/inject 的底层工作原理以及它如何自动联动校验、重置与表单提交。为什么需要自定义表单项Vant 的 Form 在提交时会遍历所有子级 Field通过getValues按name收集每个表单项的值// packages/vant/src/form/Form.tsx const getValues () children.reduceRecordstring, unknown((form, field) { if (field.name ! undefined) { form[field.name] field.formValue.value; } return form; }, {});而每个 Field 的formValue并不是简单地取modelValue它会优先读取“自定义值”。当你在input插槽中放置了自己的组件时Form 实际收集到的值就来自该自定义组件——这正是useCustomFieldValue的用武之地。基本用法原文档给出的完整流程分为两步先在自定义组件内调用useCustomFieldValue并传入取值回调再把自定义组件放进 Field 的input插槽。第一步自定义组件中注册取值函数在自定义组件如MyComponent.vue的setup中调用useCustomFieldValue传入一个返回表单项值的回调函数// MyComponent.vue import { ref } from vue; import { useCustomFieldValue } from vant/use; export default { setup() { const myValue ref(0); // 此处传入的值会替代 Field 组件内部的 value useCustomFieldValue(() myValue.value); return { myValue }; }, };回调返回的值可以是任意类型unknown不仅限于字符串——数字、对象、数组都支持表单提交时该值会被原样写入结果。第二步在 Field 的 input 插槽中挂载自定义组件在 Form 中通过van-field的name属性指定该字段在提交结果中的键名并在#input插槽中渲染自定义组件van-form !-- 这是一个自定义表单项 -- !-- 当表单提交时会包括 useCustomFieldValue 中传入的值 -- van-field namemy-field label自定义表单项 template #input my-component / /template /van-field /van-form提交表单后submit事件回调中的values对象将包含{ my-field: myValue 的值 }。注意Field 的input插槽说明见 packages/vant/src/field/README.zh-CN.md指出使用此插槽后与原生输入框相关的属性和事件将失效如maxlength、clearable等输入行为由你的自定义组件接管。Form 的 README 也专门提到“Vant 支持在 Form 组件中插入自定义的表单项”见 packages/vant/src/form/README.zh-CN.md。底层原理一次 provide / inject 协作Field 侧注入上下文Field 在 setup 中创建了一个customValue引用并通过 Vue 的provide向所有子组件暴露校验与重置能力见 packages/vant/src/field/Field.tsxprovide(CUSTOM_FIELD_INJECTION_KEY, { customValue, resetValidation, validateWithTrigger, });对应的formValue计算属性则优先采用自定义值// packages/vant/src/field/Field.tsx const formValue computed(() { if (customValue.value slots.input) { return customValue.value(); } return props.modelValue; });也就是说只有同时满足“子组件已注册自定义值”和“存在 input 插槽”两个条件时Field 提交给 Form 的值才会取自自定义组件否则回退到常规的modelValue。useCustomFieldValue 侧注入并注册useCustomFieldValue的实现位于 packages/vant-use/src/useCustomFieldValue/index.ts核心逻辑如下export const CUSTOM_FIELD_INJECTION_KEY: InjectionKeyCustomFieldInjectionValue Symbol(van-field); export function useCustomFieldValue(customValue: () unknown) { const field inject(CUSTOM_FIELD_INJECTION_KEY, null); if (field !field.customValue.value) { field.customValue.value customValue; watch(customValue, () { field.resetValidation(); field.validateWithTrigger(onChange); }); } }几个关键点值得注意注入键CUSTOM_FIELD_INJECTION_KEY是Symbol(van-field)。如果组件不在 Field 的input插槽上下文中inject返回null调用会被静默忽略因此务必把自定义组件放在 Field 内部。只注册一次if (field !field.customValue.value)保证每个 Field 只接受第一个注册的回调重复调用不会覆盖已注册的值。自动联动校验watch(customValue, ...)监听取值回调的依赖变化如myValue.value改变随后自动执行resetValidation()清空旧校验状态并调用validateWithTrigger(onChange)按onChange触发时机重新校验Form 的validateTrigger默认是onBlur见 packages/vant/src/form/Form.tsx。这意味着自定义组件内部值变化时校验、错误提示与提交值会同步更新无需手动干预。Form 侧收集与提交Form 在submit时先validate()全部字段再触发submit事件携带values见 packages/vant/src/form/Form.tsx。由于getValues读取的是field.formValue.value而该计算属性在自定义场景下返回的是你注册的回调结果所以自定义表单项自然被纳入校验与取值链路校验失败时同样会触发failed事件并可配合scrollToError滚动定位。API 参考useCustomFieldValue的类型定义与参数如下原文档 API 部分function useCustomFieldValue(customValue: () unknown): void;参数说明类型默认值customValue获取表单项值的函数() unknown-该函数返回void没有返回值也不需要在模板中引用它只负责把取值回调注册给最近的 Field 父级。内置组件中的实际应用useCustomFieldValue并非只服务于第三方自定义组件Vant 自身的多个表单类组件在放入 Field 的input插槽时也复用了这套机制例如SwitchuseCustomFieldValue(() props.modelValue)Checkbox 与 CheckboxGroupRadioGroupStepperSliderRateUploader也就是说当你写下van-fieldtemplate #inputvan-switch v-modelxxx //template/van-field时Switch 正是通过useCustomFieldValue把自己的modelValue注册给 Field从而让 Form 的提交结果与校验逻辑正确拿到开关状态。这从侧面验证了该函数的通用性与正确用法任意具备内部状态、且能提供取值函数的组件都可以借此成为 Form 的一员。最佳实践与注意事项取值回调必须可被响应式追踪watch(customValue, ...)依赖回调在求值过程中访问的响应式依赖如ref。若回调返回的是固定常量则值永远不会变化也就不会触发重新校验应确保回调内部引用ref/reactive等响应式状态。放置位置决定上下文useCustomFieldValue必须在 Field 组件树内调用通常是input插槽中的子组件否则inject取不到 Field 提供的上下文注册会静默失败。一个 Field 只注册一个自定义值由于实现中只写入首个回调若插槽内存在多个组件同时调用后注册者将被忽略。如需组合多个状态可在单个回调中聚合例如返回一个对象。校验规则仍定义在 Field 上自定义表单项的rules、required等校验配置照常写在van-field上Form 校验时使用的是自定义值因此pattern、validator拿到的value就是自定义回调的返回值空值判断逻辑见 packages/vant/src/field/utils.ts 中的isEmptyValue与runSyncRule。值的类型自由回调返回unknown意味着你可以让 Form 直接收集对象、数组等复合结构而不必像原生输入那样先序列化为字符串。小结useCustomFieldValue是 Vant 打通“自定义 UI”与“标准表单能力”的关键桥梁通过Symbol(van-field)注入键 provide/inject上下文把自定义组件的值无缝接入 Field 的formValue计算链路并在值变化时自动重置与触发校验。无论是自研组件还是像 Switch、Slider、Rate 这类内置组件都能借助它获得与原生表单项一致的提交、校验体验。【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表