2026/9/12 15:32:05

Vant 4 ContactEdit 联系人编辑组件完全指南:表单校验、事件回调与主题定制

Vant 4 ContactEdit 联系人编辑组件完全指南:表单校验、事件回调与主题定制 Vant 4 ContactEdit 联系人编辑组件完全指南表单校验、事件回调与主题定制【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant导读ContactEdit 是 Vant 4 移动端组件库中负责编辑并保存联系人信息的表单型组件通常与 ContactList 联系人列表、ContactCard 联系人卡片 组合构成完整的地址簿 / 收货人管理流程。本指南以 ContactEdit 官方文档 为主体结合 ContactEdit.tsx、index.less 等源码与 测试用例系统讲解其 Props/Events 全量 API、内置表单校验逻辑、编辑与新增两种模式以及基于 CSS 变量的主题定制方案。读完本文你将能够独立完成一个带校验、带默认联系人开关、支持编辑与删除的联系人表单页面。组件定位与应用场景ContactEdit 面向的典型业务场景是用户在下单流程中维护收货人/联系人信息包括姓名、手机号并可标记该联系人为默认。组件本身是一个自包含的表单内部基于 Vant 的 Form 表单 与 Field 输入框 构建在提交前自动完成姓名必填、手机号格式两类校验并把校验通过后的表单内容通过save事件交还给业务方持久化。在 Vant 内部ContactEdit与ContactList、ContactCard、AddressEdit等组件共享同一套联系人类别数据模型ContactEditInfo数据结构的字段名name、tel、isDefault与联系人列表组件保持对齐方便在同一页面中双向传值。快速引入与组件注册Vant 4 全面基于 Vue 3 与 TypeScript 构建使用前需确认项目已安装vant包并处于 Vue 3 环境。文档给出了全局注册方式import { createApp } from vue; import { ContactEdit } from vant; const app createApp(); app.use(ContactEdit);除了全局注册Vant 也支持按需引入。从源码看组件在 index.ts 中通过withInstall包装后导出并同时注册了全局组件名VanContactEditimport { withInstall } from ../utils; import _ContactEdit from ./ContactEdit; export const ContactEdit withInstall(_ContactEdit); export default ContactEdit; export { contactEditProps } from ./ContactEdit; export type { ContactEditInfo, ContactEditProps } from ./ContactEdit; export type { ContactEditThemeVars } from ./types; declare module vue { export interface GlobalComponents { VanContactEdit: typeof ContactEdit; } }因此模板中可以直接使用van-contact-editkebab-case或VanContactEditTypeScript 环境还能获得全局组件类型提示。若采用按需引入如使用unplugin-vue-components则无需app.use()直接import { ContactEdit } from vant后在局部注册即可更多注册方式可参考 Vant 文档的组件注册章节。代码演示编辑联系人表单的完整写法文档中的基础用法演示了编辑模式下最典型的使用形态。其对应实现可在仓库的 demo/index.vue 中看到模板部分与文档示例一致van-contact-edit is-edit show-set-default :contact-infoeditingContact set-default-label设为默认联系人 saveonSave deleteonDelete /import { ref } from vue; import { showToast } from vant; export default { setup() { const editingContact ref({ tel: , name: , }); const onSave (contactInfo) showToast(保存); const onDelete (contactInfo) showToast(删除); return { onSave, onDelete, editingContact, }; }, };这个示例的关键点在于is-edit控制是否展示删除按钮源码 ContactEdit.tsx 中删除按钮仅在props.isEdit为真时渲染也就是说新增联系人场景下不应传入该属性show-set-defaultset-default-label控制默认联系人栏仅当showSetDefault为真时渲染设为默认联系人的开关行set-default-label用于自定义该行文案contact-info为受控初值以ref维护编辑时传入已有联系人数据新增时传入空对象{ tel: , name: }save/delete回调两个事件都会把当前表单内容对象作为回调参数传出便于业务层执行保存接口或删除接口。从 demo 源码可以看出演示页面在保存/删除后只是showToast提示真实项目中应在回调里调用接口并跳转或刷新列表页。API 全量解析Props 参数以下参数来自 ContactEdit.tsx 的contactEditProps定义与官方文档两者完全一致参数说明类型默认值contact-info联系人信息ContactEditInfo{}is-edit是否为编辑联系人booleanfalseis-saving是否显示保存按钮加载动画booleanfalseis-deleting是否显示删除按钮加载动画booleanfalsetel-validator手机号格式校验函数(tel: string) booleanisMobileshow-set-default是否显示默认联系人栏booleanfalseset-default-label默认联系人栏文案string-结合源码补充两点容易被忽略的实现细节contact-info的默认值并非直接共享对象而是default: () extend({}, DEFAULT_CONTACT)每次实例化都会生成新的{ tel: , name: }避免多个实例间意外共享引用。组件内部通过reactive维护一份表单副本并通过watch(() props.contactInfo, ...)在外部数据变化时同步测试用例 index.spec.ts 专门验证了setProps 更新 contactInfo 后提交表单save 事件携带最新数据这一行为tel-validator的默认校验器是 Vant 工具函数isMobile实现在 utils/basic.ts它先剥离非数字/连字符字符再匹配((86)|(86))?1\d{10}中国大陆 11 位手机号可带 86/86 前缀或0[0-9-]{10,13}带区号的座机号。若业务需要其他手机号规则如海外号码传入自定义校验函数即可例如:tel-validator(tel) /^1[3-9]\d{9}$/.test(tel)。Events 事件事件名说明回调参数save点击保存按钮时触发content表单内容delete点击删除按钮时触发content表单内容change-default切换是否为默认联系人时触发checked是否默认源码中事件声明为emits: [save, delete, changeDefault]ContactEdit.tsx需要注意 Vue 3 中 kebab-case 的事件在模板里写作change-default组件内使用 camelCase 的changeDefault。save事件的触发逻辑值得展开保存按钮的nativeTypesubmit整个组件外层包着一个Form onSubmit{onSave}因此保存事件由表单提交驱动。而onSave内部有防重复提交判断——if (!props.isSaving) emit(save, contact)。这意味着业务侧收到save事件后应把is-saving置为true同时可配合保存按钮的loading动画在接口返回后再置回false从而既展示加载态又防止重复提交。同理is-deleting控制删除按钮的 loading 态。change-default在用户拨动设为默认联系人的 Switch 时触发回调参数为开关的布尔值。源码 ContactEdit.tsx 中该开关直接双向绑定contact.isDefault业务侧通常用它同步到后端默认联系人标记。ContactEditInfo 数据结构ContactEditInfo是组件对外交换的联系人数据模型类型定义位于 ContactEdit.tsxexport type ContactEditInfo { tel: string; name: string; isDefault?: boolean; };键名说明类型name联系人姓名stringtel联系人手机号stringisDefault是否默认boolean | undefined注意isDefault是可选字段新增联系人时通常为undefined只有用户主动打开开关后才变为true/false。save/delete事件回调参数content即为该结构的完整对象可直接用于接口提交。类型定义组件对外导出以下类型供业务侧在 TypeScript 中做类型收窄import type { ContactEditInfo, ContactEditProps } from vant;此外 index.ts 还导出了ContactEditThemeVars用于主题变量类型与contactEditPropsprops 定义对象其中ContactEditProps由ExtractPropTypestypeof contactEditProps推导而来保证类型与运行时 props 定义始终一致。内置表单校验机制ContactEdit 的校验不依赖业务方手写而是由组件内部两个 Field 的rules完成见 ContactEdit.tsx姓名字段rules [{ required: true, message: t(nameEmpty) }]即姓名必填未填写时展示请填写姓名错误文案手机号字段rules [{ validator: props.telValidator, message: t(telInvalid) }]即通过tel-validator默认isMobile校验失败时展示请填写正确的电话错误文案。文案通过 Vant 国际化机制提供默认中文在 locale/lang/zh-CN.ts 中定义name: 姓名、tel: 电话、save: 保存、delete: 删除、nameEmpty: 请填写姓名、telInvalid: 请填写正确的电话切换语言环境会自动跟随。姓名字段还设置了maxlength30限制输入长度。测试用例 index.spec.ts 完整覆盖了这套校验链路姓名为空时提交表单断言.van-field__error-message渲染出错误提示快照比对电话为空时提交表单同样断言错误提示渲染校验通过后提交断言save事件携带的contactInfo与传入值逐字段相等更新contact-infoprop 后再提交断言事件携带最新数据is-edit模式下点击删除按钮会弹出删除确认对话框van-dialog点击确认后delete事件被触发。其中删除操作弹出确认框这一行为由 demo 测试中.van-dialog__confirm的点击可见index.spec.ts说明组件在真实使用中删除属于二次确认的破坏性操作业务回调里收到delete事件时数据已被确认过。编辑模式与新增模式的区别通过 Props 组合ContactEdit 可以同时服务新增与编辑两种场景场景contact-infois-edit删除按钮新增联系人{ tel: , name: }或空对象false不传不渲染编辑联系人传入已有联系人对象true渲染点击后触发delete从源码 ContactEdit.tsx 可以确认删除按钮的渲染条件就是props.isEdit因此新增模式下组件天然只有保存一个主按钮。编辑模式下将列表页选中的联系人对象传给contact-info组件内部watch会同步副本用户修改后提交即可。主题定制CSS 变量与 ConfigProviderContactEdit 的样式完全通过 CSS 变量驱动支持两种定制方式直接覆盖:root下的变量或借助 ConfigProvider 组件 按作用域动态配置。组件暴露的样式变量定义在 index.less 中与官方文档表格一一对应名称默认值描述--van-contact-edit-paddingvar(--van-padding-md)组件整体内边距--van-contact-edit-fields-radiusvar(--van-radius-md)输入区域圆角--van-contact-edit-buttons-paddingvar(--van-padding-xl) 0按钮区域内边距--van-contact-edit-button-margin-bottomvar(--van-padding-sm)按钮下外边距--van-contact-edit-button-font-sizevar(--van-font-size-lg)按钮字号--van-contact-edit-field-label-width4.1em输入框标签宽度所有默认值都引用了 Vant 基础设计令牌如--van-padding-md、--van-radius-md、--van-font-size-lg因此定制时建议同样基于这些基础变量做相对调整保持视觉体系一致。类型层面types.ts 定义了ContactEditThemeVars对应上述六个变量名的驼峰形式如contactEditFieldLabelWidth?: string在 TS 项目中使用 ConfigProvider 的theme-vars时能获得类型提示。最佳实践小结受控与异步提交contact-info作为初始数据源配合is-saving实现防重复提交 loading 态保存接口成功后再更新列表数据或跳转校验交给组件姓名必填、手机号格式均由内置 rules 完成仅当业务规则不同如海外手机号时才覆盖tel-validator删除需二次确认组件内部已接入删除确认对话框业务回调中执行删除接口即可无需重复弹窗与联系人列表联动ContactEditInfo结构与 ContactList 数据模型对齐可在列表页选中后直接传入编辑页保存后回写列表形成完整闭环样式定制优先走 CSS 变量通过 ConfigProvider 或全局覆盖上述六个变量即可完成品牌化改造无需侵入组件内部样式。延伸阅读组件完整源码ContactEdit.tsx组件类型定义types.ts 与 index.ts样式实现index.less测试用例test/index.spec.ts、test/demo.spec.ts配套组件ContactList 联系人列表、ContactCard 联系人卡片底层依赖Form 表单、Field 输入框、ConfigProvider【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考