Skip to content

Commit 7447c50

Browse files
vaebekagol
authored andcommitted
fix(tag-input): 移除 render setup直接导出,打开关闭suggestionList面板逻辑更新
1 parent bf33d96 commit 7447c50

File tree

1 file changed

+68
-101
lines changed

1 file changed

+68
-101
lines changed
Lines changed: 68 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { defineComponent, ref, computed, nextTick, watch, SetupContext, getCurrentInstance } from 'vue';
22
import { createI18nTranslate } from '../../locale/create';
3+
import clickoutsideDirective from '../../shared/devui-directive/clickoutside';
34
import removeBtnSvg from './icon-remove';
45
import { Suggestion, TagInputProps, tagInputProps } from './tag-input-types';
56
import './tag-input.scss';
@@ -14,6 +15,9 @@ const KEYS_MAP = {
1415

1516
export default defineComponent({
1617
name: 'DTagInput',
18+
directives: {
19+
clickoutside: clickoutsideDirective,
20+
},
1721
props: tagInputProps,
1822
emits: ['update:tags', 'update:suggestionList', 'valueChange'],
1923
setup(props: TagInputProps, ctx: SetupContext) {
@@ -69,8 +73,14 @@ export default defineComponent({
6973
isInputBoxFocus.value = true;
7074
};
7175
const onInputBlur = () => {
76+
// isInputBoxFocus.value = false;
77+
};
78+
79+
// 点击元素外部区域关闭Suggestion选择
80+
const closeSuggestion = () => {
7281
isInputBoxFocus.value = false;
7382
};
83+
7484
const handleEnter = () => {
7585
let res = { [props.displayProperty]: tagInputVal.value };
7686
if (tagInputVal.value === '' && mergedSuggestions.value.length === 0) {
@@ -119,20 +129,23 @@ export default defineComponent({
119129
}
120130
};
121131

122-
const removeTag = ($event: MouseEvent, tagIdx: number) => {
132+
const removeTag = ($event: Event, tagIdx: number) => {
123133
$event.preventDefault();
124134
ctx.emit('update:suggestionList', add(props.suggestionList, props.tags[tagIdx]));
125135
const newTags = remove(props.tags, tagIdx);
126136
ctx.emit('valueChange', props.tags, newTags);
127137
ctx.emit('update:tags', newTags);
138+
128139
nextTick(() => {
129140
tagInputRef.value?.focus();
130141
});
131142
};
132-
const onSuggestionItemClick = ($event: MouseEvent, itemIndex: number) => {
143+
const onSuggestionItemClick = ($event: Event, itemIndex: number) => {
133144
$event.preventDefault();
134145
const target = mergedSuggestions.value[itemIndex];
135146
const newTags = add(props.tags, target);
147+
148+
136149
const newSuggestions = remove(props.suggestionList, target.__index);
137150
ctx.emit('valueChange', props.tags, newTags);
138151
ctx.emit('update:tags', newTags);
@@ -144,119 +157,73 @@ export default defineComponent({
144157
return !props.disabled && !isTagsLimit.value && isInputBoxFocus.value;
145158
});
146159

147-
return {
148-
tagInputRef,
149-
tagInputVal,
150-
isInputBoxFocus,
151-
onInput,
152-
onInputFocus,
153-
onInputBlur,
154-
removeTag,
155-
onSuggestionItemClick,
156-
onInputKeydown,
157-
isShowSuggestion,
158-
mergedSuggestions,
159-
selectIndex,
160-
isTagsLimit,
161-
t,
162-
};
163-
},
164-
render() {
165-
const {
166-
tagInputVal,
167-
isInputBoxFocus,
168-
disabled,
169-
disabledText,
170-
isTagsLimit,
171-
maxTagsText,
172-
displayProperty,
173-
tags,
174-
onInputKeydown,
175-
onInputFocus,
176-
onInputBlur,
177-
onInput,
178-
onSuggestionItemClick,
179-
removeTag,
180-
placeholder,
181-
spellcheck,
182-
isShowSuggestion,
183-
noData,
184-
mergedSuggestions,
185-
selectIndex,
186-
maxTags,
187-
t,
188-
} = this;
189-
190160
const inputBoxCls = {
191161
'devui-tags': true,
192162
'devui-form-control': true,
193163
'devui-dropdown-origin': true,
194164
'devui-dropdown-origin-open': isInputBoxFocus,
195-
'devui-disabled': disabled,
165+
'devui-disabled': props.disabled,
196166
};
197167
const tagInputCls = {
198168
input: true,
199169
'devui-input': true,
200170
'invalid-tag': false,
201171
};
202-
const tagInputStyle = [`display:${disabled ? 'none' : 'block'};`];
172+
const tagInputStyle = [`display:${props.disabled ? 'none' : 'block'};`];
203173

204-
const noDataTpl = <li class="devui-suggestion-item devui-disabled">{noData}</li>;
174+
const noDataTpl = <li class="devui-suggestion-item devui-disabled">{props.noData}</li>;
205175

206-
return (
207-
<div class="devui-tags-host" tabindex="-1">
208-
<div class={inputBoxCls} style={['box-shadow: none;']}>
209-
<ul class="devui-tag-list" title={disabled ? disabledText : ''}>
210-
{tags.map((tag, tagIdx) => {
211-
return (
212-
<li class="devui-tag-item">
213-
<span>{tag[displayProperty]}</span>
214-
{!disabled && (
215-
<a class="remove-button" onMousedown={($event) => removeTag($event, tagIdx)}>
216-
{removeBtnSvg}
217-
</a>
218-
)}
219-
</li>
220-
);
221-
})}
176+
return () => (<div class="devui-tags-host" tabIndex="-1" v-clickoutside={closeSuggestion}>
177+
<div class={inputBoxCls} style={['box-shadow: none;']}>
178+
<ul class="devui-tag-list" title={props.disabled ? props.disabledText : ''}>
179+
{props.tags.map((tag, tagIdx) => {
180+
return (
181+
<li class="devui-tag-item">
182+
<span>{tag[props.displayProperty]}</span>
183+
{!props.disabled && (
184+
<a class="remove-button" onClick={($event: Event) => removeTag($event, tagIdx)}>
185+
{removeBtnSvg}
186+
</a>
187+
)}
188+
</li>
189+
);
190+
})}
191+
</ul>
192+
<input
193+
type="text"
194+
ref="tagInputRef"
195+
value={tagInputVal.value}
196+
class={tagInputCls}
197+
style={tagInputStyle}
198+
onKeyDown={onInputKeydown}
199+
onFocus={onInputFocus}
200+
onBlur={onInputBlur}
201+
onInput={($event: InputEvent) => onInput($event)}
202+
placeholder={isTagsLimit.value ? `${props.maxTagsText || t('maxTagsText')} ${props.maxTags}` : props.placeholder}
203+
spellCheck={props.spellcheck}
204+
disabled={isTagsLimit.value}
205+
/>
206+
</div>
207+
{isShowSuggestion.value && (
208+
<div class="devui-tags-autocomplete devui-dropdown-menu">
209+
<ul class="devui-suggestion-list">
210+
{mergedSuggestions.value.length === 0
211+
? noDataTpl
212+
: mergedSuggestions.value.map((item: Suggestion, index: number) => {
213+
return (
214+
<li
215+
class={{ 'devui-suggestion-item': true, selected: index === selectIndex.value }}
216+
onClick={($event: Event) => {
217+
onSuggestionItemClick($event, index);
218+
}}
219+
>
220+
{item[props.displayProperty]}
221+
</li>
222+
);
223+
})}
222224
</ul>
223-
<input
224-
type="text"
225-
ref="tagInputRef"
226-
value={tagInputVal}
227-
class={tagInputCls}
228-
style={tagInputStyle}
229-
onKeydown={onInputKeydown}
230-
onFocus={onInputFocus}
231-
onBlur={onInputBlur}
232-
onInput={($event: InputEvent) => onInput($event)}
233-
placeholder={isTagsLimit ? `${maxTagsText || t('maxTagsText')} ${maxTags}` : placeholder}
234-
spellcheck={spellcheck}
235-
disabled={isTagsLimit}
236-
/>
237225
</div>
238-
{!isShowSuggestion ? (
239-
''
240-
) : (
241-
<div class="devui-tags-autocomplete devui-dropdown-menu">
242-
<ul class="devui-suggestion-list">
243-
{mergedSuggestions.length === 0
244-
? noDataTpl
245-
: mergedSuggestions.map((item: Suggestion, index: number) => {
246-
return (
247-
<li
248-
class={{ 'devui-suggestion-item': true, selected: index === selectIndex }}
249-
onMousedown={($event) => {
250-
onSuggestionItemClick($event, index);
251-
}}>
252-
{item[displayProperty]}
253-
</li>
254-
);
255-
})}
256-
</ul>
257-
</div>
258-
)}
259-
</div>
260-
);
226+
)}
227+
</div>);
261228
},
262229
});

0 commit comments

Comments
 (0)