mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2024-12-21 04:50:14 +08:00
feat(tree-select): add check-strategy prop (#758)
* feat(tree-select): 增加勾选指定中策略属性 * feat(tree-select): 更新日志 * feat(tree): update treemate to add check strategy * feat(select): disabled option hide close iocn * feat(tree): 兼容合并leaf-only与子策略属性 * feat: 回显值跟随策略优化 * feat: 优化回显结果 * Update TreeSelect.tsx * Apply suggestions from code review Co-authored-by: 07akioni <07akioni2@gmail.com>
This commit is contained in:
parent
29577a22d2
commit
6ccbe869c1
@ -112,6 +112,7 @@
|
||||
### Feats
|
||||
|
||||
- `n-loading-bar` add `loading-bar-style` props, closes [#457](https://github.com/TuSimple/naive-ui/issues/457).
|
||||
- `n-tree-select` add `check-strategy` prop.
|
||||
- `n-button` add `text-color` prop.
|
||||
- `n-form` export `FormValidationError` type.
|
||||
- `n-popconfirm` support not show action components, closes [#770](https://github.com/TuSimple/naive-ui/issues/770).
|
||||
|
@ -112,6 +112,7 @@
|
||||
### Feats
|
||||
|
||||
- `n-loading-bar` 新增 `loading-bar-style` 属性,关闭 [#457](https://github.com/TuSimple/naive-ui/issues/457)
|
||||
- `n-tree-select` 增加 `check-strategy` 属性.
|
||||
- `n-button` 新增 `text-color` 属性
|
||||
- `n-form` 导出 `FormValidationError` 类型
|
||||
- `n-popconfirm` 支持不显示操作组件,关闭 [#770](https://github.com/TuSimple/naive-ui/issues/770)
|
||||
|
121
src/tree-select/demos/enUS/check-strategy.demo.md
Normal file
121
src/tree-select/demos/enUS/check-strategy.demo.md
Normal file
@ -0,0 +1,121 @@
|
||||
# Set Check Strategy
|
||||
|
||||
# all: show all checked node; parent: show all checked parent node when all child node are checked; child: show all child node
|
||||
|
||||
```html
|
||||
<n-tree-select
|
||||
multiple
|
||||
cascade
|
||||
checkable
|
||||
checkStrategy="parent"
|
||||
:options="options"
|
||||
:default-value="['Dig It', 'go']"
|
||||
@update:value="updateValue"
|
||||
/>
|
||||
```
|
||||
|
||||
```js
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
return {
|
||||
options: [
|
||||
{
|
||||
label: 'Rubber Soul',
|
||||
key: 'Rubber Soul',
|
||||
children: [
|
||||
{
|
||||
label:
|
||||
"Everybody's Got Something to Hide Except Me and My Monkey",
|
||||
key: "Everybody's Got Something to Hide Except Me and My Monkey"
|
||||
},
|
||||
{
|
||||
label: 'Drive My Car',
|
||||
key: 'Drive My Car',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
label: 'Norwegian Wood',
|
||||
key: 'Norwegian Wood'
|
||||
},
|
||||
{
|
||||
label: "You Won't See",
|
||||
key: "You Won't See",
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
label: 'Nowhere Man',
|
||||
key: 'Nowhere Man'
|
||||
},
|
||||
{
|
||||
label: 'Think For Yourself',
|
||||
key: 'Think For Yourself'
|
||||
},
|
||||
{
|
||||
label: 'The Word',
|
||||
key: 'The Word'
|
||||
},
|
||||
{
|
||||
label: 'Michelle',
|
||||
key: 'Michelle',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
label: 'What goes on',
|
||||
key: 'What goes on'
|
||||
},
|
||||
{
|
||||
label: 'Girl',
|
||||
key: 'Girl'
|
||||
},
|
||||
{
|
||||
label: "I'm looking through you",
|
||||
key: "I'm looking through you"
|
||||
},
|
||||
{
|
||||
label: 'In My Life',
|
||||
key: 'In My Life'
|
||||
},
|
||||
{
|
||||
label: 'Wait',
|
||||
key: 'Wait'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Let It Be',
|
||||
key: 'Let It Be Album',
|
||||
children: [
|
||||
{
|
||||
label: 'Two Of Us',
|
||||
key: 'Two Of Us'
|
||||
},
|
||||
{
|
||||
label: 'Dig A Pony',
|
||||
key: 'Dig A Pony'
|
||||
},
|
||||
{
|
||||
label: 'Across The Universe',
|
||||
key: 'Across The Universe',
|
||||
children: [
|
||||
{
|
||||
label: 'Dig It',
|
||||
key: 'Dig It'
|
||||
},
|
||||
{
|
||||
label: 'go',
|
||||
key: 'go'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
updateValue: (values) => {
|
||||
console.log(values)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
@ -9,6 +9,7 @@ basic
|
||||
custom-field
|
||||
multiple
|
||||
checkbox
|
||||
check-strategy
|
||||
filterable
|
||||
debug
|
||||
```
|
||||
@ -21,6 +22,7 @@ debug
|
||||
| --- | --- | --- | --- |
|
||||
| cascade | `boolean` | `false` | Whether to do cascade check when use checkboxes. |
|
||||
| checkable | `boolean` | `false` | Whether to use checkbox to select value. |
|
||||
| check-strategy | `string` | `'all'` | The way to show checked options. `all`: Show all checked node. `parent`: Show all checked parent node when all child node are checked. `child`: show all child node. |
|
||||
| children-field | `string` | `'children'` | The children field in `TreeSelectOption`. |
|
||||
| clearable | `boolean` | `false` | Whether it's clearable. |
|
||||
| consistent-menu-width | `boolean` | `true` | Whether to make menu's width consistent with input. Set to `true` will disable virtual scroll. |
|
||||
|
119
src/tree-select/demos/zhCN/check-strategy.demo.md
Normal file
119
src/tree-select/demos/zhCN/check-strategy.demo.md
Normal file
@ -0,0 +1,119 @@
|
||||
# 指定勾选策略
|
||||
|
||||
```html
|
||||
<n-tree-select
|
||||
multiple
|
||||
cascade
|
||||
checkable
|
||||
check-strategy="parent"
|
||||
:options="options"
|
||||
:default-value="['Dig It', 'go']"
|
||||
@update:value="updateValue"
|
||||
/>
|
||||
```
|
||||
|
||||
```js
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
return {
|
||||
options: [
|
||||
{
|
||||
label: 'Rubber Soul',
|
||||
key: 'Rubber Soul',
|
||||
children: [
|
||||
{
|
||||
label:
|
||||
"Everybody's Got Something to Hide Except Me and My Monkey",
|
||||
key: "Everybody's Got Something to Hide Except Me and My Monkey"
|
||||
},
|
||||
{
|
||||
label: 'Drive My Car',
|
||||
key: 'Drive My Car',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
label: 'Norwegian Wood',
|
||||
key: 'Norwegian Wood'
|
||||
},
|
||||
{
|
||||
label: "You Won't See",
|
||||
key: "You Won't See",
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
label: 'Nowhere Man',
|
||||
key: 'Nowhere Man'
|
||||
},
|
||||
{
|
||||
label: 'Think For Yourself',
|
||||
key: 'Think For Yourself'
|
||||
},
|
||||
{
|
||||
label: 'The Word',
|
||||
key: 'The Word'
|
||||
},
|
||||
{
|
||||
label: 'Michelle',
|
||||
key: 'Michelle',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
label: 'What goes on',
|
||||
key: 'What goes on'
|
||||
},
|
||||
{
|
||||
label: 'Girl',
|
||||
key: 'Girl'
|
||||
},
|
||||
{
|
||||
label: "I'm looking through you",
|
||||
key: "I'm looking through you"
|
||||
},
|
||||
{
|
||||
label: 'In My Life',
|
||||
key: 'In My Life'
|
||||
},
|
||||
{
|
||||
label: 'Wait',
|
||||
key: 'Wait'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Let It Be',
|
||||
key: 'Let It Be Album',
|
||||
children: [
|
||||
{
|
||||
label: 'Two Of Us',
|
||||
key: 'Two Of Us'
|
||||
},
|
||||
{
|
||||
label: 'Dig A Pony',
|
||||
key: 'Dig A Pony'
|
||||
},
|
||||
{
|
||||
label: 'Across The Universe',
|
||||
key: 'Across The Universe',
|
||||
children: [
|
||||
{
|
||||
label: 'Dig It',
|
||||
key: 'Dig It'
|
||||
},
|
||||
{
|
||||
label: 'go',
|
||||
key: 'go'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
updateValue: (values) => {
|
||||
console.log(values)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
@ -9,6 +9,7 @@ basic
|
||||
custom-field
|
||||
multiple
|
||||
checkbox
|
||||
check-strategy
|
||||
filterable
|
||||
debug
|
||||
```
|
||||
@ -21,6 +22,7 @@ debug
|
||||
| --- | --- | --- | --- |
|
||||
| cascade | `boolean` | `false` | 使用 checkbox 进行多选时是否级联 |
|
||||
| checkable | `boolean` | `false` | 是否使用 checkbox 进行选择 |
|
||||
| check-strategy | `string` | `'all'` | 设置勾选策略来指定显示的勾选节点,`all`:显示全部选中节点;`parent`:只显示父节点(当父节点下所有子节点都选中时);`child`:只显示子节点 |
|
||||
| children-field | `string` | `'children'` | 替代 `TreeSelectOption` 中的 children 字段名 |
|
||||
| clearable | `boolean` | `false` | 是否可清除 |
|
||||
| consistent-menu-width | `boolean` | `true` | 是否使菜单宽度和输入框一致,打开会禁用虚拟滚动 |
|
||||
|
@ -47,7 +47,7 @@ import type {
|
||||
TreeSelectOption,
|
||||
Value
|
||||
} from './interface'
|
||||
import { treeSelectInjectionKey } from './interface'
|
||||
import { treeSelectInjectionKey, CheckStrategy } from './interface'
|
||||
import {
|
||||
treeOption2SelectOption,
|
||||
filterTree,
|
||||
@ -81,6 +81,7 @@ const props = {
|
||||
},
|
||||
filterable: Boolean,
|
||||
leafOnly: Boolean,
|
||||
checkStrategy: String as PropType<CheckStrategy>,
|
||||
maxTagCount: [String, Number] as PropType<number | 'responsive'>,
|
||||
multiple: Boolean,
|
||||
showPath: Boolean,
|
||||
@ -285,11 +286,17 @@ export default defineComponent({
|
||||
if (Array.isArray(mergedValue)) {
|
||||
const res: SelectBaseOption[] = []
|
||||
const { value: treeMate } = dataTreeMateRef
|
||||
const { checkedKeys } = treeMate.getCheckedKeys(mergedValue)
|
||||
const { keyField, labelField } = props
|
||||
mergedValue.forEach((value) => {
|
||||
checkedKeys.forEach((value) => {
|
||||
const tmNode = treeMate.getNode(value)
|
||||
if (tmNode !== null) {
|
||||
res.push(
|
||||
if (
|
||||
props.checkStrategy === 'all' ||
|
||||
(props.checkStrategy === 'parent' && !tmNode.isLeaf) ||
|
||||
(props.checkStrategy === 'child' && tmNode.isLeaf)
|
||||
) {
|
||||
res.push(
|
||||
showPath
|
||||
? treeOption2SelectOptionWithPath(
|
||||
tmNode,
|
||||
@ -299,6 +306,7 @@ export default defineComponent({
|
||||
)
|
||||
: treeOption2SelectOption(tmNode, labelField)
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
return res
|
||||
@ -691,6 +699,7 @@ export default defineComponent({
|
||||
mergedClsPrefix,
|
||||
filteredTreeInfo,
|
||||
checkable,
|
||||
checkStrategy,
|
||||
multiple
|
||||
} = this
|
||||
return withDirectives(
|
||||
@ -723,6 +732,7 @@ export default defineComponent({
|
||||
checkedKeys={this.treeCheckedKeys}
|
||||
selectedKeys={this.treeSelectedKeys}
|
||||
checkable={checkable}
|
||||
checkStrategy={checkStrategy}
|
||||
cascade={this.mergedCascade}
|
||||
leafOnly={this.leafOnly}
|
||||
multiple={this.multiple}
|
||||
|
@ -41,3 +41,5 @@ export interface TreeSelectInjection {
|
||||
|
||||
export const treeSelectInjectionKey: InjectionKey<TreeSelectInjection> =
|
||||
Symbol('tree-select')
|
||||
|
||||
export type CheckStrategy = 'all' | 'parent' | 'child'
|
||||
|
@ -28,6 +28,7 @@ import { call, createDataKey, warn } from '../../_utils'
|
||||
import type { ExtractPublicPropTypes, MaybeArray } from '../../_utils'
|
||||
import { NxScrollbar } from '../../scrollbar'
|
||||
import type { ScrollbarInst } from '../../scrollbar'
|
||||
import { CheckStrategy } from '../../tree-select/src/interface'
|
||||
import { treeLight } from '../styles'
|
||||
import type { TreeTheme } from '../styles'
|
||||
import NTreeNode from './TreeNode'
|
||||
@ -126,6 +127,7 @@ const treeProps = {
|
||||
blockLine: Boolean,
|
||||
disabled: Boolean,
|
||||
checkedKeys: Array as PropType<Key[]>,
|
||||
checkStrategy: String as PropType<CheckStrategy>,
|
||||
defaultCheckedKeys: {
|
||||
type: Array as PropType<Key[]>,
|
||||
default: () => []
|
||||
@ -263,6 +265,9 @@ export default defineComponent({
|
||||
cascade: props.cascade
|
||||
})
|
||||
})
|
||||
const mergedCheckStrategyRef = computed(() =>
|
||||
props.leafOnly ? 'child' : props.checkStrategy
|
||||
)
|
||||
const displayedCheckedKeysRef = computed(() => {
|
||||
return checkedStatusRef.value.checkedKeys
|
||||
})
|
||||
@ -567,7 +572,8 @@ export default defineComponent({
|
||||
checked ? 'check' : 'uncheck'
|
||||
](node.key, displayedCheckedKeysRef.value, {
|
||||
cascade: props.cascade,
|
||||
leafOnly: props.leafOnly
|
||||
leafOnly: props.leafOnly,
|
||||
checkStrategy: mergedCheckStrategyRef.value
|
||||
})
|
||||
doUpdateCheckedKeys(checkedKeys)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user