从 v3 升级到 v4

介绍

本文档提供了从 Vant 3 到 Vant 4 的升级指南。

安装 Vant 4

首先你需要安装 Vant 4 以及 @vant/compat

@vant/compat 是一个兼容包,可以帮助你从 Vant 3 过渡到 Vant 4。

  1. # 通过 npm 安装
  2. npm add vant@^4 @vant/compat@^1
  3. # 通过 yarn 安装
  4. yarn add vant@^4 @vant/compat@^1
  5. # 通过 pnpm 安装
  6. pnpm add vant@^4 @vant/compat@^1

你也可以直接修改 package.jsondependencies 字段中的版本号,修改完成后需要重新安装依赖。

  1. {
  2. "dependencies": {
  3. - "vant": "^3.0.0",
  4. + "vant": "^4.0.0",
  5. + "@vant/compat": "^1.0.0",
  6. }
  7. }

调整按需引入方式

移除 babel-plugin-import

从 Vant 4.0 开始,将不再支持 babel-plugin-import,请移除项目中依赖的 babel-plugin-import 插件。

只需要删除 babel.config.js 中的以下代码即可:

  1. module.exports = {
  2. plugins: [
  3. - ['import', {
  4. - libraryName: 'vant',
  5. - libraryDirectory: 'es',
  6. - style: true
  7. - }, 'vant']
  8. ]
  9. };

收益

移除 babel-plugin-import 主要带来以下收益:

  • 不再强依赖 Babel 编译,项目可以使用 SWC、esbuild 等现代编译工具,进而提升编译效率。
  • 不再受到 babel-plugin-import 的 import 限制,可以从 Vant 中导入除组件以外的内容,比如 Vant 4 中新增的 showToast 方法,或是 buttonProps 对象:
  1. import { showToast, buttonProps } from 'vant';

样式引入方案

移除 babel-plugin-import 对项目的 JS 体积不会有影响,因为 Vant 默认支持通过 Tree Shaking 来移除不需要的 JS 代码。

而 CSS 代码的引入方式可以从以下两种方式中进行选择:

  • 在项目中全量引入 Vant 的样式文件:
  1. import 'vant/lib/index.css';

组件重构

介绍

在 Vant 4 中,一共有三个组件被完全重构,它们是:

  • Area
  • Picker
  • DatetimePicker

这三个组件之所以被重构,是因为在之前的版本中,Picker 组件的 API 设计存在一些不合理的设计,导致大家在使用时经常遇到问题,比如:

  • Picker columns 数据格式定义不合理,容易产生误解
  • Picker 数据流不清晰,暴露了过多的实例方法来对数据进行操作
  • DatetimePicker 逻辑过于复杂,经常在边界场景下出现 bug

为了解决上述问题,我们在 v4 版本中对 Picker 组件进行了重构,同时也重构了基于 Picker 派生出的 AreaDatetimePicker 组件。如果你的项目中使用了这三个组件,请仔细阅读文档并进行升级。

Picker 组件重构

主要变更

  • 支持通过 v-model 绑定当前选中的值,移除 default-index 属性
  • 重新定义了 columns 属性的结构
  • 移除了操作内部数据的实例方法,仅保留 confirm 方法
  • 新增 getSelectedOptions 实例方法
  • 调整了 confirmcancelchange 事件的参数
  • 重命名 item-height 属性为 option-height
  • 重命名 visible-item-count 属性为 visible-option-num

详细用法请参见 Picker 组件文档

DatetimePicker 组件重构

DatetimePicker 组件被拆分为三个子组件:

  • TimePicker: 用于时间选择,包括时、分、秒。
  • DatePicker: 用于日期选择,包括年、月、日。
  • PickerGroup: 用于结合多个 Picker 选择器组件,在一次交互中完成多个值的选择。

同时,TimePicker 和 DatePicker 组件也基于新版 Picker 组件进行重构,并优化了部分 API 设计。

主要变更

以下是 TimePicker 和 DatePicker 的主要 API 变化,更多细节请参考 TimePickerDatePicker 文档。

  • v-model 绑定的值调整为数组格式
  • 新增 columns-type 属性,用于控制选项类型和顺序
  • 移除 type 属性和 columns-order 属性
  • 移除 getPicker 方法
  • 调整 confirmcancelchange 事件的参数,与 Picker 组件保持一致

Vant 4 不再提供旧版的 DatetimePicker 组件,使用 PickerGroup 组件可以实现更灵活、更丰富的交互效果,具体用法请参考 PickerGroup 组件文档。

Area 组件重构

Area 组件是基于 Picker 组件进行封装的,因此本次升级也对 Area 组件进行了内部逻辑的重构,并优化了部分 API。

主要变更

  • 支持通过 v-model 绑定当前选中的值
  • 移除 reset 方法,现在可以通过修改 v-model 来进行重置
  • 移除 is-oversea-code 属性
  • 调整 confirmcancelchange 事件的参数,与 Picker 组件保持一致
  • 重命名 value 属性为 modelValue
  • 重命名 item-height 属性为 option-height
  • 重命名 visible-item-count 属性为 visible-option-num

详细用法请参见 Area 组件文档

API 调整

Dialog 调用方式调整

在 Vant 3 中,Dialog 是一个函数,调用函数可以快速唤起全局的弹窗组件,而 Dialog.Component 才是 Dialog 组件对象,这与大部分组件的用法存在差异,容易导致使用错误。

为了更符合直觉,我们在 Vant 4 中调整了 Dialog 的调用方式,将 Dialog() 函数重命名为 showDialog(),并让 Dialog 直接指向组件对象。

  1. // Vant 3
  2. Dialog(); // 函数调用
  3. Dialog.Component; // 组件对象
  4. // Vant 4
  5. showDialog(); // 函数调用
  6. Dialog; // 组件对象

由于 Dialog 变为了组件对象,Dialog 上挂载的其他方法也进行了重命名,新旧 API 的映射关系如下:

  1. Dialog(); // -> showDialog()
  2. Dialog.alert(); // -> showDialog()
  3. Dialog.confirm(); // -> showConfirmDialog()
  4. Dialog.close(); // -> closeDialog();
  5. Dialog.setDefaultOptions(); // -> setDialogDefaultOptions()
  6. Dialog.resetDefaultOptions(); // -> resetDialogDefaultOptions()

兼容方案

为了便于旧版本代码迁移至 v4,我们提供了兼容方案,你可以使用 @vant/compat 中导出的 Dialog 对象来兼容原有代码。

@vant/compat 中引用 Dialog 方法:

  1. import { Dialog } from '@vant/compat';
  2. Dialog();
  3. Dialog.close();

@vant/compat 中导出的 Dialog 与 Vant 3 中的 Dialog 拥有完全一致的 API 和行为,因此你只需要修改 Dialog 的引用路径,其他代码可以保持不变。

在项目完成升级到 Vant v4 后,建议在迭代中逐步替换为新的 showDialog 等方法,并移除 @vant/compat 包。

Toast 调用方式调整

Vant 4 中,Toast 组件的调用方式也进行了调整,与 Dialog 组件的改动一致:

  1. // Vant 3
  2. Toast(); // 函数调用
  3. // Vant 4
  4. showToast(); // 函数调用
  5. Toast; // 组件对象

Toast 上挂载的其他方法也进行了重命名,新旧 API 的映射关系如下:

  1. Toast(); // -> showToast()
  2. Toast.fail(); // -> showFailToast()
  3. Toast.success(); // -> showSuccessToast()
  4. Toast.loading(); // -> showLoadingToast()
  5. Toast.clear(); // -> closeToast()
  6. Toast.setDefaultOptions(); // -> setToastDefaultOptions()
  7. Toast.resetDefaultOptions(); // -> resetToastDefaultOptions()

同时,Vant 4 将不再在 this 对象上全局注册 $toast 方法,这意味着 this 对象上将无法访问到 $toast

兼容方案

为了便于代码迁移,我们提供了兼容方案,你可以使用 @vant/compat 中导出的 Toast 对象来兼容原有代码。

  1. import { Toast } from '@vant/compat';
  2. Toast();
  3. Toast.clear();

@vant/compat 中导出的 Toast 与 Vant 3 中的 Toast 拥有完全一致的 API 和行为,因此你只需要修改 Toast 的引用路径,其他代码可以保持不变。

Notify 调用方式调整

Vant 4 中,Notify 组件的调用方式也进行了调整,与 Dialog 组件的改动一致:

  1. // Vant 3
  2. Notify(); // 函数调用
  3. Notify.Component; // 组件对象
  4. // Vant 4
  5. showNotify(); // 函数调用
  6. Notify; // 组件对象

Notify 上挂载的其他方法也进行了重命名,新旧 API 的映射关系如下:

  1. Notify(); // -> showNotify()
  2. Notify.clear(); // -> closeNotify()
  3. Notify.setDefaultOptions(); // -> setNotifyDefaultOptions()
  4. Notify.resetDefaultOptions(); // -> resetNotifyDefaultOptions()

同时,Vant 4 将不再在 this 对象上全局注册 $notify 方法,这意味着 this 对象上将无法访问到 $notify

兼容方案

为了便于代码迁移,我们提供了兼容方案,你可以使用 @vant/compat 中导出的 Notify 对象来兼容原有代码。

  1. import { Notify } from '@vant/compat';
  2. Notify();
  3. Notify.clear();

@vant/compat 中导出的 Notify 与 Vant 3 中的 Notify 拥有完全一致的 API 和行为,因此你只需要修改 Notify 的引用路径,其他代码可以保持不变。

ImagePreview 调用方式调整

Vant 4 中,ImagePreview 组件的调用方式也进行了调整,与 ImagePreview 组件的改动一致:

  1. // Vant 3
  2. ImagePreview(); // 函数调用
  3. ImagePreview.Component; // 组件对象
  4. // Vant 4
  5. showImagePreview(); // 函数调用
  6. ImagePreview; // 组件对象

兼容方案

为了便于代码迁移,我们提供了兼容方案,你可以使用 @vant/compat 中导出的 ImagePreview 对象来兼容原有代码。

  1. import { ImagePreview } from '@vant/compat';
  2. ImagePreview();

@vant/compat 中导出的 ImagePreview 与 Vant 3 中的 ImagePreview 拥有完全一致的 API 和行为,因此你只需要修改 ImagePreview 的引用路径,其他代码可以保持不变。

事件命名调整

从 Vant 4 开始,所有的事件均采用 Vue 官方推荐的驼峰格式进行命名。

  1. // Vant 3
  2. emit('click-input');
  3. // Vant 4
  4. emit('clickInput');

这项改动不影响原有的模板代码,Vue 会自动在模板中对事件名进行格式转换,因此你无须做任何更改。

  1. <!-- 以下代码可以照常运行,无须做任何更改 -->
  2. <van-field @click-input="onClick" />

如果你在 JSX 中使用 Vant 组件,需要将监听的事件名调整为驼峰格式,原有的中划线格式将不再生效,新的监听方式更加符合 JSX 本身的规范:

  1. // Vant 3
  2. <Field onClick-input={onClick} />
  3. // Vant 4
  4. <Field onClickInput={onClick} />

其他 API 调整

在 Vant 4.0 版本中,以下 API 进行了不兼容更新:

AddressEdit

  • 移除 show-postal 属性
  • 移除 postal-validator 属性
  • change-area 事件的参数调整为 PickerOption[] 类型
  • 移除未在文档中标注的 getArea 实例方法

Popup

Popup 的 CSS 样式进行了一定调整,如果你在 Popup 组件上添加了一些自定义的 CSS 样式,请确认本次升级是否对项目中的 UI 产生影响。

  • 默认添加了 box-sizing: border-box 样式
  • 调整了 position="center" 时的水平居中方式,以解决弹窗宽度无法正确自适应的问题:
  1. // Vant 3
  2. .van-popup--center {
  3. left: 50%;
  4. transform: translate3d(-50%, -50%, 0);
  5. }
  6. // Vant 4
  7. .van-popup--center {
  8. left: 0;
  9. right: 0;
  10. width: fit-content;
  11. max-width: calc(100vw - var(--van-padding-md) * 2);
  12. margin: 0 auto;
  13. transform: translateY(-50%);
  14. }

Tabs

  • 移除了 clickdisabled 事件,请使用 click-tab 事件代替

样式调整

主色调统一

在之前的版本中,Vant 组件有两种主色调,部分组件采用蓝色(#1989fa)作为主色调,另一部分则采用红色(#ee0a24)。

为了保持色彩规范的一致性,我们在 Vant 4 中对主色调进行统一,所有组件均采用蓝色作为主色调。

以下组件的主色调由红色调整为蓝色:

  • AddressEdit
  • AddressList
  • Card
  • Calendar
  • Cascader
  • ContactList
  • ContactEdit
  • CouponList
  • Dialog
  • DropdownMenu
  • IndexBar
  • Sidebar
  • Steps
  • Tabs
  • TreeSelect

移除 Less 变量

目前 Vant 已经支持了基于 CSS 变量的主题定制能力,相较于 Less 定制更加灵活。因此,Vant 4 将不再提供基于 Less 的主题定制方式。

这意味着 Vant 的 npm 包中将不再会包含 .less 样式源文件,只会提供编译后的 .css 样式文件。

如果你的项目正在使用旧版的 Less 主题定制,请使用 ConfigProvider 全局配置 组件进行替换。

简化 CSS 变量名

考虑到 代码体积使用便捷性,我们对部分 CSS 变量的名称进行了简化,在变量名中使用了更简短的单词,以减小代码体积。

本次升级涉及以下变量名变更:

  1. animation-duration -> duration
  2. animation-timing-function-enter -> ease-out
  3. animation-timing-function-leave -> ease-in
  4. background-color -> background
  5. background-color-light -> background-2
  6. border-radius -> radius
  7. border-width-base -> border-width
  8. box-shadow -> shadow
  9. font-family -> font
  10. font-weight-bold -> font-bold
  11. price-integer-font -> price-font
  12. text-link -> link
  13. transition-duration -> duration

由于涉及的 CSS 变量较多,建议在代码仓库中进行全局匹配和替换。

对于 ConfigProvider 组件,我们新增了 ConfigProviderThemeVars 类型定义,提供完整的类型提示。在 TypeScript 代码中,你可以通过类型提示来确保主题变量被正确替换。

  1. import type { ConfigProviderThemeVars } from 'vant';
  2. const themeVars: ConfigProviderThemeVars = {
  3. sliderBarHeight: '4px',
  4. };

从 v3 升级到 v4 - 图1