diff --git a/breaking-changes.md b/breaking-changes.md
index daf6cfc31..ea43013c2 100644
--- a/breaking-changes.md
+++ b/breaking-changes.md
@@ -1,6 +1,24 @@
# 不兼容更新
-## 重命名徽标属性
+## v-model API 变更
+
+以下改动是为了适配 Vue 3 的 v-model API 用法变更:
+
+- Circle: `v-model` 重命名为 `v-model:currentRate`
+- Popup: `v-model` 重命名为 `v-model:show`
+- Switch: v-model 对应的属性 `value` 重命名为 `modelValue`,事件由 `input` 重命名为 `update:modelValue`
+- Sidebar: v-model 对应的属性 `activeKey` 重命名为 `modelValue`,事件由 `input` 重命名为 `update:modelValue`
+- TreeSelect: `active-id.sync` 重命名为 `v-model:active-id`
+- TreeSelect: `main-active-index.sync` 重命名为 `v-model:main-active-index`
+
+## API 命名调整
+
+以下改动是为了规范 API 命名:
+
+- TreeSelect: `navclick` 事件重命名为 `click-nav`
+- TreeSelect: `itemclick` 事件重命名为 `click-item`
+
+### 重命名徽标属性
在之前的版本中,我们通过 info 属性来展示图标右上角的徽标信息,为了表达更符合社区的命名习惯,我们将这个属性重命名为 badge,影响以下组件:
@@ -14,13 +32,6 @@
同时内部使用的 Info 组件也会重命名为 Badge。
-## v-model API 变更
-
-- Circle: `v-model` 调整为 `v-model:currentRate`
-- Popup: `v-model` 调整为 `v-model:show`
-- Switch: v-model 对应的属性 `value` 调整为 `modelValue`,事件由 `input` 调整为 `update:modelValue`
-- Sidebar: v-model 对应的属性 `activeKey` 调整为 `modelValue`,事件由 `input` 调整为 `update:modelValue`
-
## 废弃个别组件
- SwitchCell: 移除此组件,可以直接使用 Cell 和 Switch 组件代替
diff --git a/src-next/tree-select/README.md b/src-next/tree-select/README.md
new file mode 100644
index 000000000..e49f49298
--- /dev/null
+++ b/src-next/tree-select/README.md
@@ -0,0 +1,170 @@
+# TreeSelect
+
+### Install
+
+```js
+import Vue from 'vue';
+import { TreeSelect } from 'vant';
+
+Vue.use(TreeSelect);
+```
+
+## Usage
+
+### Radio Mode
+
+```html
+
+```
+
+```js
+export default {
+ data() {
+ return {
+ items,
+ activeId: 1,
+ activeIndex: 0,
+ };
+ },
+};
+```
+
+### Multiple Mode
+
+```html
+
+```
+
+```js
+export default {
+ data() {
+ return {
+ items,
+ activeIds: [1, 2],
+ activeIndex: 0,
+ };
+ },
+};
+```
+
+### Custom Content
+
+```html
+
+
+
+
+
+
+```
+
+```js
+export default {
+ data() {
+ return {
+ active: 0,
+ items: [{ text: 'Group 1' }, { text: 'Group 2' }],
+ };
+ },
+};
+```
+
+### Show Badge
+
+```html
+
+```
+
+```js
+export default {
+ data() {
+ return {
+ activeIndex: 0,
+ items: [
+ { text: 'Group 1', children: [], dot: true },
+ { text: 'Group 2', children: [], badge: 5 },
+ ],
+ };
+ },
+};
+```
+
+## API
+
+### Props
+
+| Attribute | Description | Type | Default |
+| --- | --- | --- | --- |
+| items | Required datasets for the component | _Item[]_ | `[]` |
+| height | Height | _number \| string_ | `300` |
+| main-active-index | The index of selected parent node | _number \| string_ | `0` |
+| active-id | Id of selected item | _number \| string \|
(number \| string)[]_ | `0` |
+| max `v2.2.0` | Maximum number of selected items | _number \| string_ | `Infinity` |
+| selected-icon `v2.9.0` | Selected icon | _string_ | `success` |
+
+### Events
+
+| Event | Description | Arguments |
+| --- | --- | --- |
+| click-nav | triggered when parent node is selected | index: index of selected parent |
+| click-item | triggered when item is selected | data: selected item |
+
+### Slots
+
+| Name | Description |
+| ------- | -------------------- |
+| content | Custom right content |
+
+### Data Structure of Item
+
+`items` should be an array contains specified tree objects.
+
+In every tree object, `text` property defines `id` stands for the unique key while the `children` contains sub-tree objects.
+
+```js
+[
+ {
+ // name of the parent node
+ text: 'Group 1',
+ // badge
+ badge: 3,
+ // Whether to show red dot
+ dot: true,
+ // ClassName of parent node
+ className: 'my-class',
+ // leaves of this parent node
+ children: [
+ {
+ // name of the leaf node
+ text: 'Washington',
+ // id of the leaf node, component highlights leaf node by comparing the activeId with this.
+ id: 1,
+ // disable options
+ disabled: true,
+ },
+ {
+ text: 'Baltimore',
+ id: 2,
+ },
+ ],
+ },
+];
+```
diff --git a/src-next/tree-select/README.zh-CN.md b/src-next/tree-select/README.zh-CN.md
new file mode 100644
index 000000000..5c1a51cda
--- /dev/null
+++ b/src-next/tree-select/README.zh-CN.md
@@ -0,0 +1,180 @@
+# TreeSelect 分类选择
+
+### 引入
+
+```js
+import Vue from 'vue';
+import { TreeSelect } from 'vant';
+
+Vue.use(TreeSelect);
+```
+
+## 代码演示
+
+### 单选模式
+
+`item`为分类显示所需的数据,数据格式见下方示例。`main-active-index`表示左侧高亮选项的索引,`active-id`表示右侧高亮选项的 id
+
+```html
+
+```
+
+```js
+export default {
+ data() {
+ return {
+ items,
+ activeId: 1,
+ activeIndex: 0,
+ };
+ },
+};
+```
+
+### 多选模式
+
+`active-id`为数组格式时,可以选中多个右侧选项
+
+```html
+
+```
+
+```js
+export default {
+ data() {
+ return {
+ items,
+ activeIds: [1, 2],
+ activeIndex: 0,
+ };
+ },
+};
+```
+
+### 自定义内容
+
+通过`content`插槽可以自定义右侧区域的内容
+
+```html
+
+
+
+
+
+
+```
+
+```js
+export default {
+ data() {
+ return {
+ active: 0,
+ items: [{ text: '分组 1' }, { text: '分组 2' }],
+ };
+ },
+};
+```
+
+### 徽标提示
+
+设置`dot`属性后,会在图标右上角展示一个小红点。设置`badge`属性后,会在图标右上角展示相应的徽标
+
+```html
+
+```
+
+```js
+export default {
+ data() {
+ return {
+ activeIndex: 0,
+ items: [
+ { text: '浙江', children: [], dot: true },
+ { text: '江苏', children: [], badge: 5 },
+ ],
+ };
+ },
+};
+```
+
+## API
+
+### Props
+
+| 参数 | 说明 | 类型 | 默认值 |
+| --- | --- | --- | --- |
+| items | 分类显示所需的数据 | _Item[]_ | `[]` |
+| height | 高度,默认单位为`px` | _number \| string_ | `300` |
+| main-active-index | 左侧选中项的索引 | _number \| string_ | `0` |
+| active-id | 右侧选中项的 id,支持传入数组 | _number \| string \|
(number \| string)[]_ | `0` |
+| max `v2.2.0` | 右侧项最大选中个数 | _number \| string_ | `Infinity` |
+| selected-icon `v2.9.0` | 自定义右侧栏选中状态的图标 | _string_ | `success` |
+
+### Events
+
+| 事件名 | 说明 | 回调参数 |
+| ---------- | -------------------- | ------------------------- |
+| click-nav | 点击左侧导航时触发 | index:被点击的导航的索引 |
+| click-item | 点击右侧选择项时触发 | data: 该点击项的数据 |
+
+### Slots
+
+| 名称 | 说明 |
+| ------- | ------------------ |
+| content | 自定义右侧区域内容 |
+
+### Item 数据结构
+
+`items` 整体为一个数组,数组内包含一系列描述分类的对象,每个分类里,`text`表示当前分类的名称,`children`表示分类里的可选项。
+
+```js
+[
+ {
+ // 导航名称
+ text: '所有城市',
+ // 导航名称右上角徽标,2.5.6 版本开始支持
+ badge: 3,
+ // 是否在导航名称右上角显示小红点
+ dot: true,
+ // 导航节点额外类名
+ className: 'my-class',
+ // 该导航下所有的可选项
+ children: [
+ {
+ // 名称
+ text: '温州',
+ // id,作为匹配选中状态的标识符
+ id: 1,
+ // 禁用选项
+ disabled: true,
+ },
+ {
+ text: '杭州',
+ id: 2,
+ },
+ ],
+ },
+];
+```
diff --git a/src-next/tree-select/demo/data-en.ts b/src-next/tree-select/demo/data-en.ts
new file mode 100644
index 000000000..57d93f4e0
--- /dev/null
+++ b/src-next/tree-select/demo/data-en.ts
@@ -0,0 +1,65 @@
+const group1 = [
+ {
+ text: 'Delaware',
+ id: 1,
+ },
+ {
+ text: 'Florida',
+ id: 2,
+ },
+ {
+ text: 'Georqia',
+ id: 3,
+ disabled: true,
+ },
+ {
+ text: 'Indiana',
+ id: 4,
+ },
+];
+
+const group2 = [
+ {
+ text: 'Alabama',
+ id: 5,
+ },
+ {
+ text: 'Kansas',
+ id: 6,
+ },
+ {
+ text: 'Louisiana',
+ id: 7,
+ },
+ {
+ text: 'Texas',
+ id: 8,
+ },
+];
+
+const group3 = [
+ {
+ text: 'Alabama',
+ id: 9,
+ },
+ {
+ text: 'Kansas',
+ id: 10,
+ },
+];
+
+export const enUSData = [
+ {
+ text: 'Group 1',
+ children: group1,
+ },
+ {
+ text: 'Group 2',
+ children: group2,
+ },
+ {
+ text: 'Group 3',
+ disabled: true,
+ children: group3,
+ },
+];
diff --git a/src-next/tree-select/demo/data-zh.ts b/src-next/tree-select/demo/data-zh.ts
new file mode 100644
index 000000000..04096a180
--- /dev/null
+++ b/src-next/tree-select/demo/data-zh.ts
@@ -0,0 +1,65 @@
+const zhejiang = [
+ {
+ text: '杭州',
+ id: 1,
+ },
+ {
+ text: '温州',
+ id: 2,
+ },
+ {
+ text: '宁波',
+ id: 3,
+ disabled: true,
+ },
+ {
+ text: '义乌',
+ id: 4,
+ },
+];
+
+const jiangsu = [
+ {
+ text: '南京',
+ id: 5,
+ },
+ {
+ text: '无锡',
+ id: 6,
+ },
+ {
+ text: '徐州',
+ id: 7,
+ },
+ {
+ text: '苏州',
+ id: 8,
+ },
+];
+
+const fujian = [
+ {
+ text: '泉州',
+ id: 9,
+ },
+ {
+ text: '厦门',
+ id: 10,
+ },
+];
+
+export const zhCNData = [
+ {
+ text: '浙江',
+ children: zhejiang,
+ },
+ {
+ text: '江苏',
+ children: jiangsu,
+ },
+ {
+ text: '福建',
+ disabled: true,
+ children: fujian,
+ },
+];
diff --git a/src-next/tree-select/demo/index.vue b/src-next/tree-select/demo/index.vue
new file mode 100644
index 000000000..5ba206521
--- /dev/null
+++ b/src-next/tree-select/demo/index.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src-next/tree-select/index.js b/src-next/tree-select/index.js
new file mode 100644
index 000000000..b123d891f
--- /dev/null
+++ b/src-next/tree-select/index.js
@@ -0,0 +1,128 @@
+// Utils
+import { createNamespace, addUnit, isDef } from '../utils';
+
+// Components
+import Icon from '../icon';
+import Sidebar from '../sidebar';
+import SidebarItem from '../sidebar-item';
+
+const [createComponent, bem] = createNamespace('tree-select');
+
+export default createComponent({
+ props: {
+ max: {
+ type: [Number, String],
+ default: Infinity,
+ },
+ items: {
+ type: Array,
+ default: () => [],
+ },
+ height: {
+ type: [Number, String],
+ default: 300,
+ },
+ activeId: {
+ type: [Number, String, Array],
+ default: 0,
+ },
+ selectedIcon: {
+ type: String,
+ default: 'success',
+ },
+ mainActiveIndex: {
+ type: [Number, String],
+ default: 0,
+ },
+ },
+
+ emits: [
+ 'click-nav',
+ 'click-item',
+ 'update:activeId',
+ 'update:mainActiveIndex',
+ ],
+
+ setup(props, { emit, slots }) {
+ return function () {
+ const { items, height, activeId, selectedIcon, mainActiveIndex } = props;
+
+ const selectedItem = items[+mainActiveIndex] || {};
+ const subItems = selectedItem.children || [];
+ const isMultiple = Array.isArray(activeId);
+
+ function isActiveItem(id) {
+ return isMultiple ? activeId.indexOf(id) !== -1 : activeId === id;
+ }
+
+ const Navs = items.map((item) => (
+
+ ));
+
+ function Content() {
+ if (slots.content) {
+ return slots.content();
+ }
+
+ return subItems.map((item) => (
+
{
+ if (!item.disabled) {
+ let newActiveId = item.id;
+ if (isMultiple) {
+ newActiveId = activeId.slice();
+
+ const index = newActiveId.indexOf(item.id);
+
+ if (index !== -1) {
+ newActiveId.splice(index, 1);
+ } else if (newActiveId.length < props.max) {
+ newActiveId.push(item.id);
+ }
+ }
+
+ emit('update:activeId', newActiveId);
+ emit('click-item', item);
+ }
+ }}
+ >
+ {item.text}
+ {isActiveItem(item.id) && (
+
+ )}
+
+ ));
+ }
+
+ return (
+
+
{
+ emit('update:mainActiveIndex', index);
+ emit('click-nav', index);
+ }}
+ >
+ {Navs}
+
+
{Content()}
+
+ );
+ };
+ },
+});
diff --git a/src-next/tree-select/index.less b/src-next/tree-select/index.less
new file mode 100644
index 000000000..047d95414
--- /dev/null
+++ b/src-next/tree-select/index.less
@@ -0,0 +1,51 @@
+@import '../style/var';
+
+.van-tree-select {
+ position: relative;
+ display: flex;
+ font-size: @tree-select-font-size;
+ user-select: none;
+
+ &__nav {
+ flex: 1;
+ overflow-y: auto;
+ background-color: @tree-select-nav-background-color;
+ -webkit-overflow-scrolling: touch;
+
+ &-item {
+ padding: @tree-select-nav-item-padding;
+ }
+ }
+
+ &__content {
+ flex: 2;
+ overflow-y: auto;
+ background-color: @tree-select-content-background-color;
+ -webkit-overflow-scrolling: touch;
+ }
+
+ &__item {
+ position: relative;
+ padding: 0 32px 0 @padding-md;
+ font-weight: @font-weight-bold;
+ line-height: @tree-select-item-height;
+ cursor: pointer;
+
+ &--active {
+ color: @tree-select-item-active-color;
+ }
+
+ &--disabled {
+ color: @tree-select-item-disabled-color;
+ cursor: not-allowed;
+ }
+ }
+
+ &__selected {
+ position: absolute;
+ top: 50%;
+ right: @padding-md;
+ margin-top: -@padding-xs;
+ font-size: @tree-select-item-selected-size;
+ }
+}
diff --git a/src-next/tree-select/test/__snapshots__/demo.spec.js.snap b/src-next/tree-select/test/__snapshots__/demo.spec.js.snap
new file mode 100644
index 000000000..ef3181896
--- /dev/null
+++ b/src-next/tree-select/test/__snapshots__/demo.spec.js.snap
@@ -0,0 +1,90 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders demo correctly 1`] = `
+
+
+
+
+
+
+
杭州
+
+
温州
+
+
宁波
+
义乌
+
+
+
+
+
+
+`;
diff --git a/src-next/tree-select/test/__snapshots__/index.spec.js.snap b/src-next/tree-select/test/__snapshots__/index.spec.js.snap
new file mode 100644
index 000000000..245f661d1
--- /dev/null
+++ b/src-next/tree-select/test/__snapshots__/index.spec.js.snap
@@ -0,0 +1,41 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`content slot 1`] = `
+
+`;
+
+exports[`empty list 1`] = `
+
+`;
+
+exports[`height prop 1`] = `
+
+`;
+
+exports[`nav info 1`] = `
+
+`;
+
+exports[`selected-icon prop 1`] = `
+city1
+
+`;
diff --git a/src-next/tree-select/test/demo.spec.js b/src-next/tree-select/test/demo.spec.js
new file mode 100644
index 000000000..5c70922b5
--- /dev/null
+++ b/src-next/tree-select/test/demo.spec.js
@@ -0,0 +1,4 @@
+import Demo from '../demo';
+import { snapshotDemo } from '../../../test/demo';
+
+snapshotDemo(Demo);
diff --git a/src-next/tree-select/test/index.spec.js b/src-next/tree-select/test/index.spec.js
new file mode 100644
index 000000000..3b45a3936
--- /dev/null
+++ b/src-next/tree-select/test/index.spec.js
@@ -0,0 +1,345 @@
+import TreeSelect from '..';
+import { mount } from '../../../test';
+
+test('empty list', () => {
+ expect(mount(TreeSelect)).toMatchSnapshot();
+});
+
+const mockItem = {
+ text: 'city1',
+ id: 1,
+};
+
+const mockItem2 = {
+ text: 'city2',
+ id: 2,
+};
+
+const mockItems = [
+ {
+ text: 'group1',
+ children: [mockItem],
+ },
+ {
+ text: 'group2',
+ children: [mockItem],
+ },
+];
+
+test('click-nav event', () => {
+ const onNavClick = jest.fn();
+ const onClickNav = jest.fn();
+
+ const wrapper = mount(TreeSelect, {
+ propsData: {
+ items: mockItems,
+ },
+ context: {
+ on: {
+ navclick: onNavClick,
+ 'click-nav': onClickNav,
+ },
+ },
+ });
+
+ const navItems = wrapper.findAll('.van-tree-select__nav-item');
+ navItems.at(1).trigger('click');
+
+ expect(onNavClick).toHaveBeenCalledWith(1);
+ expect(onClickNav).toHaveBeenCalledWith(1);
+});
+
+test('click-item event', () => {
+ const onItemClick = jest.fn();
+ const onClickItem = jest.fn();
+
+ const wrapper = mount(TreeSelect, {
+ propsData: {
+ items: mockItems,
+ },
+ context: {
+ on: {
+ itemclick: onItemClick,
+ 'click-item': onClickItem,
+ },
+ },
+ });
+
+ const items = wrapper.findAll('.van-tree-select__item');
+ items.at(0).trigger('click');
+ expect(onItemClick).toHaveBeenCalledWith(mockItem);
+ expect(onClickItem).toHaveBeenCalledWith(mockItem);
+});
+
+test('click disabled nav', () => {
+ const onClickNav = jest.fn();
+
+ const wrapper = mount(TreeSelect, {
+ propsData: {
+ items: [
+ {
+ text: 'group1',
+ children: [mockItem],
+ disabled: true,
+ },
+ ],
+ },
+ context: {
+ on: {
+ 'click-nav': onClickNav,
+ },
+ },
+ });
+
+ const items = wrapper.findAll('.van-tree-select__nav-item');
+ items.at(0).trigger('click');
+ expect(onClickNav).toHaveBeenCalledTimes(0);
+});
+
+test('click disabled item', () => {
+ const onClickItem = jest.fn();
+ const wrapper = mount(TreeSelect, {
+ propsData: {
+ items: [
+ {
+ text: 'group1',
+ children: [
+ {
+ ...mockItem,
+ disabled: true,
+ },
+ ],
+ },
+ ],
+ },
+ context: {
+ on: {
+ 'click-item': onClickItem,
+ },
+ },
+ });
+
+ const items = wrapper.findAll('.van-tree-select__item');
+ items.at(0).trigger('click');
+ expect(onClickItem).toHaveBeenCalledTimes(0);
+});
+
+test('content slot', () => {
+ const wrapper = mount(TreeSelect, {
+ propsData: {
+ items: [
+ {
+ text: 'group1',
+ },
+ ],
+ },
+ scopedSlots: {
+ content: () => 'Custom Content',
+ },
+ });
+
+ expect(wrapper).toMatchSnapshot();
+});
+
+test('height prop', () => {
+ const wrapper = mount(TreeSelect, {
+ propsData: {
+ height: '100vh',
+ },
+ });
+
+ expect(wrapper).toMatchSnapshot();
+});
+
+test('nav info', () => {
+ const wrapper = mount(TreeSelect, {
+ propsData: {
+ items: [
+ {
+ text: 'group1',
+ info: 3,
+ },
+ ],
+ },
+ });
+
+ expect(wrapper).toMatchSnapshot();
+});
+
+test('use sync modifier in main-active-index', () => {
+ const wrapper = mount({
+ template: `
+
+ `,
+ data() {
+ return {
+ mainActiveIndex: -1,
+ items: mockItems,
+ };
+ },
+ });
+
+ const navItems = wrapper.findAll('.van-tree-select__nav-item');
+ navItems.at(0).trigger('click');
+
+ expect(wrapper.vm.mainActiveIndex).toEqual(0);
+});
+
+test('use sync modifier in active-id', () => {
+ const wrapper = mount({
+ template: `
+
+ `,
+ data() {
+ return {
+ activeId: mockItem.id,
+ mainActiveIndex: 0,
+ items: [
+ {
+ text: 'group1',
+ children: [mockItem, mockItem2],
+ },
+ ],
+ };
+ },
+ });
+
+ const items = wrapper.findAll('.van-tree-select__item');
+ items.at(1).trigger('click');
+
+ expect(wrapper.vm.activeId).toEqual(mockItem2.id);
+});
+
+test('multiple select', () => {
+ const wrapper = mount({
+ template: `
+
+ `,
+ data() {
+ return {
+ activeId: [],
+ mainActiveIndex: 0,
+ items: [
+ {
+ text: 'group1',
+ children: [mockItem, mockItem2],
+ },
+ ],
+ };
+ },
+ });
+
+ const items = wrapper.findAll('.van-tree-select__item');
+ items.at(0).trigger('click');
+ items.at(1).trigger('click');
+ expect(wrapper.vm.activeId).toEqual([mockItem.id, mockItem2.id]);
+
+ items.at(0).trigger('click');
+ items.at(1).trigger('click');
+ expect(wrapper.vm.activeId).toEqual([]);
+});
+
+test('max prop', () => {
+ const wrapper = mount({
+ template: `
+
+ `,
+ data() {
+ return {
+ activeId: [],
+ items: [
+ {
+ text: 'group1',
+ children: [mockItem, mockItem2],
+ },
+ ],
+ };
+ },
+ });
+
+ const items = wrapper.findAll('.van-tree-select__item');
+ items.at(0).trigger('click');
+ items.at(1).trigger('click');
+ expect(wrapper.vm.activeId).toEqual([mockItem.id]);
+});
+
+test('className of nav', () => {
+ const wrapper = mount(TreeSelect, {
+ propsData: {
+ mainActiveIndex: 0,
+ items: [
+ {
+ text: 'group1',
+ className: 'my-class',
+ children: [],
+ },
+ ],
+ },
+ });
+
+ const items = wrapper.findAll('.van-tree-select__nav-item');
+ expect(items.at(0).element.classList.contains('my-class')).toBeTruthy();
+});
+
+test('should sync value before trigger click-item event', (done) => {
+ const wrapper = mount({
+ template: `
+
+ `,
+ data() {
+ return {
+ activeId: mockItem.id,
+ mainActiveIndex: 0,
+ items: [
+ {
+ text: 'group1',
+ children: [mockItem, mockItem2],
+ },
+ ],
+ };
+ },
+ methods: {
+ onClickItem() {
+ expect(wrapper.vm.activeId).toEqual(mockItem2.id);
+ done();
+ },
+ },
+ });
+
+ const items = wrapper.findAll('.van-tree-select__item');
+ items.at(1).trigger('click');
+});
+
+test('selected-icon prop', () => {
+ const wrapper = mount(TreeSelect, {
+ propsData: {
+ items: mockItems,
+ activeId: 1,
+ mainActiveIndex: 0,
+ selectedIcon: 'foo',
+ },
+ });
+
+ expect(wrapper.find('.van-tree-select__item')).toMatchSnapshot();
+});
diff --git a/vant.config.js b/vant.config.js
index f0e8c944e..b5c0626cd 100644
--- a/vant.config.js
+++ b/vant.config.js
@@ -302,10 +302,10 @@ module.exports = {
path: 'pagination',
title: 'Pagination 分页',
},
- // {
- // path: 'sidebar',
- // title: 'Sidebar 侧边导航',
- // },
+ {
+ path: 'sidebar',
+ title: 'Sidebar 侧边导航',
+ },
// {
// path: 'tab',
// title: 'Tab 标签页',
@@ -314,10 +314,10 @@ module.exports = {
// path: 'tabbar',
// title: 'Tabbar 标签栏',
// },
- // {
- // path: 'tree-select',
- // title: 'TreeSelect 分类选择',
- // },
+ {
+ path: 'tree-select',
+ title: 'TreeSelect 分类选择',
+ },
],
},
{
@@ -636,10 +636,10 @@ module.exports = {
path: 'pagination',
title: 'Pagination',
},
- // {
- // path: 'sidebar',
- // title: 'Sidebar',
- // },
+ {
+ path: 'sidebar',
+ title: 'Sidebar',
+ },
// {
// path: 'tab',
// title: 'Tab',
@@ -648,10 +648,10 @@ module.exports = {
// path: 'tabbar',
// title: 'Tabbar',
// },
- // {
- // path: 'tree-select',
- // title: 'TreeSelect',
- // },
+ {
+ path: 'tree-select',
+ title: 'TreeSelect',
+ },
],
},
{