Commit 60577d6720fd3f8d4d1a88b20ab902d6161a0eec
1 parent
953bfc6f
feat(tree): add searchable function
添加搜索功能相关属性和方法 close: #1057
Showing
5 changed files
with
51 additions
and
7 deletions
CHANGELOG.zh_CN.md
src/components/Tree/src/Tree.vue
... | ... | @@ -42,7 +42,14 @@ |
42 | 42 | name: 'BasicTree', |
43 | 43 | inheritAttrs: false, |
44 | 44 | props: basicProps, |
45 | - emits: ['update:expandedKeys', 'update:selectedKeys', 'update:value', 'change', 'check'], | |
45 | + emits: [ | |
46 | + 'update:expandedKeys', | |
47 | + 'update:selectedKeys', | |
48 | + 'update:value', | |
49 | + 'change', | |
50 | + 'check', | |
51 | + 'update:searchValue', | |
52 | + ], | |
46 | 53 | setup(props, { attrs, slots, emit, expose }) { |
47 | 54 | const state = reactive<State>({ |
48 | 55 | checkStrictly: props.checkStrictly, |
... | ... | @@ -192,7 +199,14 @@ |
192 | 199 | state.checkStrictly = strictly; |
193 | 200 | } |
194 | 201 | |
202 | + const searchText = ref(''); | |
203 | + watchEffect(() => { | |
204 | + if (props.searchValue !== searchText.value) searchText.value = props.searchValue; | |
205 | + }); | |
206 | + | |
195 | 207 | function handleSearch(searchValue: string) { |
208 | + if (searchValue !== searchText.value) searchText.value = searchValue; | |
209 | + emit('update:searchValue', searchValue); | |
196 | 210 | if (!searchValue) { |
197 | 211 | searchState.startSearch = false; |
198 | 212 | return; |
... | ... | @@ -293,6 +307,12 @@ |
293 | 307 | filterByLevel: (level: number) => { |
294 | 308 | state.expandedKeys = filterByLevel(level); |
295 | 309 | }, |
310 | + setSearchValue: (value: string) => { | |
311 | + handleSearch(value); | |
312 | + }, | |
313 | + getSearchValue: () => { | |
314 | + return searchText.value; | |
315 | + }, | |
296 | 316 | }; |
297 | 317 | |
298 | 318 | expose(instance); |
... | ... | @@ -380,6 +400,7 @@ |
380 | 400 | helpMessage={helpMessage} |
381 | 401 | onStrictlyChange={onStrictlyChange} |
382 | 402 | onSearch={handleSearch} |
403 | + searchText={unref(searchText)} | |
383 | 404 | > |
384 | 405 | {extendSlots(slots)} |
385 | 406 | </TreeHeader> | ... | ... |
src/components/Tree/src/TreeHeader.vue
... | ... | @@ -11,7 +11,7 @@ |
11 | 11 | :placeholder="t('common.searchText')" |
12 | 12 | size="small" |
13 | 13 | allowClear |
14 | - @change="handleSearch" | |
14 | + v-model:value="searchValue" | |
15 | 15 | /> |
16 | 16 | </div> |
17 | 17 | <Dropdown @click.prevent v-if="toolbar"> |
... | ... | @@ -32,7 +32,7 @@ |
32 | 32 | </template> |
33 | 33 | <script lang="ts"> |
34 | 34 | import type { PropType } from 'vue'; |
35 | - import { defineComponent, computed } from 'vue'; | |
35 | + import { defineComponent, computed, ref, watch } from 'vue'; | |
36 | 36 | |
37 | 37 | import { Dropdown, Menu, Input } from 'ant-design-vue'; |
38 | 38 | import { Icon } from '/@/components/Icon'; |
... | ... | @@ -77,10 +77,12 @@ |
77 | 77 | search: propTypes.bool, |
78 | 78 | checkAll: propTypes.func, |
79 | 79 | expandAll: propTypes.func, |
80 | + searchText: propTypes.string, | |
80 | 81 | }, |
81 | 82 | emits: ['strictly-change', 'search'], |
82 | 83 | setup(props, { emit }) { |
83 | 84 | const { t } = useI18n(); |
85 | + const searchValue = ref(''); | |
84 | 86 | |
85 | 87 | const toolbarList = computed(() => { |
86 | 88 | const { checkable } = props; |
... | ... | @@ -137,11 +139,25 @@ |
137 | 139 | } |
138 | 140 | const debounceEmitChange = useDebounceFn(emitChange, 200); |
139 | 141 | |
140 | - function handleSearch(e: ChangeEvent): void { | |
141 | - debounceEmitChange(e.target.value); | |
142 | - } | |
142 | + watch( | |
143 | + () => searchValue.value, | |
144 | + (v) => { | |
145 | + debounceEmitChange(v); | |
146 | + } | |
147 | + ); | |
148 | + watch( | |
149 | + () => props.searchText, | |
150 | + (v) => { | |
151 | + if (v !== searchValue.value) { | |
152 | + searchValue.value = v; | |
153 | + } | |
154 | + } | |
155 | + ); | |
156 | + // function handleSearch(e: ChangeEvent): void { | |
157 | + // debounceEmitChange(e.target.value); | |
158 | + // } | |
143 | 159 | |
144 | - return { t, toolbarList, handleMenuClick, handleSearch }; | |
160 | + return { t, toolbarList, handleMenuClick, searchValue }; | |
145 | 161 | }, |
146 | 162 | }); |
147 | 163 | </script> | ... | ... |
src/components/Tree/src/props.ts
... | ... | @@ -20,6 +20,7 @@ export const basicProps = { |
20 | 20 | title: propTypes.string, |
21 | 21 | toolbar: propTypes.bool, |
22 | 22 | search: propTypes.bool, |
23 | + searchValue: propTypes.string, | |
23 | 24 | checkStrictly: propTypes.bool, |
24 | 25 | clickRowToExpand: propTypes.bool.def(true), |
25 | 26 | checkable: propTypes.bool.def(false), | ... | ... |
src/components/Tree/src/typing.ts
... | ... | @@ -34,6 +34,8 @@ export interface TreeActionType { |
34 | 34 | insertNodesByKey: (opt: InsertNodeParams) => void; |
35 | 35 | deleteNodeByKey: (key: string) => void; |
36 | 36 | updateNodeByKey: (key: string, node: Omit<TreeDataItem, 'key'>) => void; |
37 | + setSearchValue: (value: string) => void; | |
38 | + getSearchValue: () => string; | |
37 | 39 | } |
38 | 40 | |
39 | 41 | export interface InsertNodeParams { | ... | ... |