mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[new feature] TreeSelect: support multiple select (#4130)
This commit is contained in:
parent
a4f65f45c8
commit
bfb3196438
@ -11,7 +11,7 @@ Vue.use(TreeSelect);
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage
|
||||
### Radio Mode
|
||||
|
||||
```html
|
||||
<van-tree-select
|
||||
@ -28,10 +28,8 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
items,
|
||||
// the index of parent item
|
||||
activeId: 1,
|
||||
mainActiveIndex: 0,
|
||||
// the id of selected item
|
||||
activeId: 1001
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@ -45,6 +43,45 @@ export default {
|
||||
}
|
||||
```
|
||||
|
||||
### Multiple Mode
|
||||
|
||||
```html
|
||||
<van-tree-select
|
||||
:items="items"
|
||||
:active-id="activeIds"
|
||||
:main-active-index="mainActiveIndex"
|
||||
@click-nav="onClickNav"
|
||||
@click-item="onClickItem"
|
||||
/>
|
||||
```
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
items,
|
||||
activeIds: 1,
|
||||
mainActiveIndex: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onClickNav(index) {
|
||||
this.mainActiveIndex = index;
|
||||
},
|
||||
onClickItem(data) {
|
||||
const { id } = data;
|
||||
const { activeIds } = this;
|
||||
|
||||
if (activeIds.indexOf(id) !== -1) {
|
||||
activeIds.splice(activeIds.indexOf(id), 1);
|
||||
} else {
|
||||
activeIds.push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
@ -11,13 +11,13 @@ Vue.use(TreeSelect);
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 基础用法
|
||||
### 单选模式
|
||||
|
||||
```html
|
||||
<van-tree-select
|
||||
:items="items"
|
||||
:main-active-index="mainActiveIndex"
|
||||
:active-id="activeId"
|
||||
:main-active-index="mainActiveIndex"
|
||||
@click-nav="onClickNav"
|
||||
@click-item="onClickItem"
|
||||
/>
|
||||
@ -28,10 +28,8 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
items,
|
||||
// 左侧高亮元素的index
|
||||
mainActiveIndex: 0,
|
||||
// 被选中元素的id
|
||||
activeId: 1
|
||||
activeId: 1,
|
||||
mainActiveIndex: 0
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@ -45,6 +43,45 @@ export default {
|
||||
}
|
||||
```
|
||||
|
||||
### 多选模式
|
||||
|
||||
```html
|
||||
<van-tree-select
|
||||
:items="items"
|
||||
:active-id="activeIds"
|
||||
:main-active-index="mainActiveIndex"
|
||||
@click-nav="onClickNav"
|
||||
@click-item="onClickItem"
|
||||
/>
|
||||
```
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
items,
|
||||
activeIds: 1,
|
||||
mainActiveIndex: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onClickNav(index) {
|
||||
this.mainActiveIndex = index;
|
||||
},
|
||||
onClickItem(data) {
|
||||
const { id } = data;
|
||||
const { activeIds } = this;
|
||||
|
||||
if (activeIds.indexOf(id) !== -1) {
|
||||
activeIds.splice(activeIds.indexOf(id), 1);
|
||||
} else {
|
||||
activeIds.push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<demo-section>
|
||||
<demo-block :title="$t('basicUsage')">
|
||||
<demo-block :title="$t('radioMode')">
|
||||
<van-tree-select
|
||||
:items="items"
|
||||
:main-active-index="mainActiveIndex"
|
||||
@ -9,6 +9,16 @@
|
||||
@itemclick="onItemClick"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('multipleMode')">
|
||||
<van-tree-select
|
||||
:items="items"
|
||||
:main-active-index="mainActiveIndex2"
|
||||
:active-id="activeIds"
|
||||
@navclick="onNavClick2"
|
||||
@itemclick="onItemClick2"
|
||||
/>
|
||||
</demo-block>
|
||||
</demo-section>
|
||||
</template>
|
||||
|
||||
@ -20,6 +30,8 @@ export default {
|
||||
group2: '浙江',
|
||||
group3: '江苏',
|
||||
group4: '福建',
|
||||
radioMode: '单选模式',
|
||||
multipleMode: '多选模式',
|
||||
city1: [{
|
||||
text: '杭州',
|
||||
id: 1
|
||||
@ -60,6 +72,8 @@ export default {
|
||||
group2: 'Group1',
|
||||
group3: 'Group2',
|
||||
group4: 'Group3',
|
||||
radioMode: 'Radio Mode',
|
||||
multipleMode: 'Multiple Mode',
|
||||
city1: [{
|
||||
text: 'Delaware',
|
||||
id: 1
|
||||
@ -99,8 +113,10 @@ export default {
|
||||
|
||||
data() {
|
||||
return {
|
||||
activeId: 1,
|
||||
activeIds: [1, 2],
|
||||
mainActiveIndex: 0,
|
||||
activeId: 1
|
||||
mainActiveIndex2: 0
|
||||
};
|
||||
},
|
||||
|
||||
@ -127,8 +143,24 @@ export default {
|
||||
onNavClick(index) {
|
||||
this.mainActiveIndex = index;
|
||||
},
|
||||
|
||||
onItemClick(data) {
|
||||
this.activeId = data.id;
|
||||
},
|
||||
|
||||
onNavClick2(index) {
|
||||
this.mainActiveIndex2 = index;
|
||||
},
|
||||
|
||||
onItemClick2(data) {
|
||||
const { id } = data;
|
||||
const { activeIds } = this;
|
||||
|
||||
if (activeIds.indexOf(id) !== -1) {
|
||||
activeIds.splice(activeIds.indexOf(id), 1);
|
||||
} else {
|
||||
activeIds.push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ export type TreeSelectChildren = {
|
||||
export type TreeSelectProps = {
|
||||
height: number | string;
|
||||
items: TreeSelectItem[];
|
||||
activeId: number | string;
|
||||
activeId: number | string | (number | string)[];
|
||||
mainActiveIndex: number;
|
||||
};
|
||||
|
||||
@ -42,6 +42,14 @@ function TreeSelect(
|
||||
const selectedItem: Partial<TreeSelectItem> = items[mainActiveIndex] || {};
|
||||
const subItems = selectedItem.children || [];
|
||||
|
||||
const isMultiple = Array.isArray(activeId);
|
||||
|
||||
function isActiveItem(id: number | string) {
|
||||
return isMultiple
|
||||
? (activeId as (number | string)[]).indexOf(id) !== -1
|
||||
: activeId === id;
|
||||
}
|
||||
|
||||
const Nav = items.map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
@ -76,7 +84,7 @@ function TreeSelect(
|
||||
class={[
|
||||
'van-ellipsis',
|
||||
bem('item', {
|
||||
active: activeId === item.id,
|
||||
active: isActiveItem(item.id),
|
||||
disabled: item.disabled
|
||||
})
|
||||
]}
|
||||
@ -90,7 +98,7 @@ function TreeSelect(
|
||||
}}
|
||||
>
|
||||
{item.text}
|
||||
{activeId === item.id && (
|
||||
{isActiveItem(item.id) && (
|
||||
<Icon name="checked" size="16px" class={bem('selected')} />
|
||||
)}
|
||||
</div>
|
||||
@ -115,7 +123,7 @@ TreeSelect.props = {
|
||||
default: 300
|
||||
},
|
||||
activeId: {
|
||||
type: [Number, String],
|
||||
type: [Number, String, Array],
|
||||
default: 0
|
||||
},
|
||||
mainActiveIndex: {
|
||||
|
@ -23,5 +23,27 @@ exports[`renders demo correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="van-tree-select" style="height: 300px;">
|
||||
<div class="van-tree-select__nav">
|
||||
<div class="van-ellipsis van-tree-select__nav-item van-tree-select__nav-item--active">所有城市</div>
|
||||
<div class="van-ellipsis van-tree-select__nav-item">浙江</div>
|
||||
<div class="van-ellipsis van-tree-select__nav-item">江苏</div>
|
||||
<div class="van-ellipsis van-tree-select__nav-item van-tree-select__nav-item--disabled">福建</div>
|
||||
</div>
|
||||
<div class="van-tree-select__content">
|
||||
<div class="van-ellipsis van-tree-select__item van-tree-select__item--active">杭州<i class="van-icon van-icon-checked van-tree-select__selected" style="font-size: 16px;">
|
||||
<!----></i></div>
|
||||
<div class="van-ellipsis van-tree-select__item van-tree-select__item--active">温州<i class="van-icon van-icon-checked van-tree-select__selected" style="font-size: 16px;">
|
||||
<!----></i></div>
|
||||
<div class="van-ellipsis van-tree-select__item van-tree-select__item--disabled">宁波</div>
|
||||
<div class="van-ellipsis van-tree-select__item">义乌</div>
|
||||
<div class="van-ellipsis van-tree-select__item">南京</div>
|
||||
<div class="van-ellipsis van-tree-select__item">无锡</div>
|
||||
<div class="van-ellipsis van-tree-select__item">徐州</div>
|
||||
<div class="van-ellipsis van-tree-select__item">苏州</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
Loading…
x
Reference in New Issue
Block a user