@@ -20,30 +20,54 @@ export default defineComponent({
20
20
const showSuggestions = ref < boolean > ( false ) ;
21
21
const currentIndex = ref < number > ( 0 ) ;
22
22
const suggestionsTop = ref < number > ( ) ;
23
+ const suggestionsLeft = ref < number > ( ) ;
23
24
const suggestions = ref < IMentionSuggestionItem [ ] > ( [ ] ) ;
24
25
const filteredSuggestions = ref < IMentionSuggestionItem [ ] > ( [ ] ) ;
25
26
const suggestionsDom = ref < HTMLDivElement > ( ) ;
26
27
const loading = computed ( ( ) => props . loading ) ;
27
28
const instance = getCurrentInstance ( ) ;
28
29
30
+ const checkShouldShowSuggestions = ( word : string ) => {
31
+ if ( word && props . trigger . includes ( word [ 0 ] ) ) {
32
+ // 需要以空格作为分割,单词尾部的 trigger 符号不生效
33
+ return word . length === 1 || ! props . trigger . includes ( word [ word . length - 1 ] ) ;
34
+ } else {
35
+ return false ;
36
+ }
37
+ } ;
38
+
39
+ const updateTextContentWithSuggestion = ( suggestion : string | number ) => {
40
+ const wordsWithoutSpace = textContext . value . split ( ' ' ) ;
41
+ const lastWordIndex = wordsWithoutSpace . length - 1 ;
42
+ const lastWord = wordsWithoutSpace [ lastWordIndex ] ;
43
+ wordsWithoutSpace [ lastWordIndex ] = `${ lastWord [ 0 ] } ${ suggestion } ` ;
44
+ textContext . value = wordsWithoutSpace . join ( ' ' ) ;
45
+ } ;
46
+
29
47
const handleUpdate = debounce ( ( val : string ) => {
30
- if ( props . trigger . includes ( val [ 0 ] ) ) {
48
+ const wordsWithoutSpace = val . split ( ' ' ) ;
49
+ const lastWordIndex = wordsWithoutSpace . length - 1 ;
50
+ const lastWord = wordsWithoutSpace [ lastWordIndex ] ;
51
+ const shouldBeActive = checkShouldShowSuggestions ( lastWord ) ;
52
+ if ( shouldBeActive ) {
31
53
showSuggestions . value = true ;
32
54
if ( props . position === 'top' ) {
33
55
setTimeout ( ( ) => {
34
- const height = window . getComputedStyle ( suggestionsDom . value as Element , null ) . height ;
56
+ const element = window . getComputedStyle ( suggestionsDom . value as Element , null ) ;
57
+ const { height, width } = element ;
35
58
suggestionsTop . value = - Number ( height . replace ( 'px' , '' ) ) ;
59
+ suggestionsLeft . value = Number ( width . replace ( 'px' , '' ) ) ;
36
60
} , 0 ) ;
37
61
}
38
62
filteredSuggestions . value = ( suggestions . value as IMentionSuggestionItem [ ] ) . filter ( ( item : IMentionSuggestionItem ) =>
39
63
String ( item [ props . dmValueParse . value as keyof IMentionSuggestionItem ] )
40
64
. toLocaleLowerCase ( )
41
- . includes ( val . slice ( 1 ) . toLocaleLowerCase ( ) )
65
+ . includes ( lastWord . slice ( 1 ) . toLocaleLowerCase ( ) )
42
66
) ;
43
67
} else {
44
68
showSuggestions . value = false ;
45
69
}
46
- emit ( 'change' , val . slice ( 1 ) ) ;
70
+ emit ( 'change' , lastWord . slice ( 1 ) ) ;
47
71
} , 300 ) ;
48
72
49
73
const handleBlur = ( e : Event ) => {
@@ -67,7 +91,8 @@ export default defineComponent({
67
91
e . stopPropagation ( ) ;
68
92
e . preventDefault ( ) ;
69
93
showSuggestions . value = false ;
70
- textContext . value = textContext . value . substring ( 0 , 1 ) + item [ props . dmValueParse . value as keyof IMentionSuggestionItem ] ;
94
+ const suggestion = item [ props . dmValueParse . value as keyof IMentionSuggestionItem ] ;
95
+ updateTextContentWithSuggestion ( suggestion ) ;
71
96
} ;
72
97
73
98
const arrowKeyDown = ( e : KeyboardEvent ) => {
@@ -102,9 +127,8 @@ export default defineComponent({
102
127
e . stopPropagation ( ) ;
103
128
e . preventDefault ( ) ;
104
129
showSuggestions . value = false ;
105
- textContext . value =
106
- textContext . value . substring ( 0 , 1 ) +
107
- filteredSuggestions . value [ currentIndex . value ] [ props . dmValueParse . value as keyof IMentionSuggestionItem ] ;
130
+ const suggestion = filteredSuggestions . value [ currentIndex . value ] [ props . dmValueParse . value as keyof IMentionSuggestionItem ] ;
131
+ updateTextContentWithSuggestion ( suggestion ) ;
108
132
emit ( 'select' , filteredSuggestions . value [ currentIndex . value ] ) ;
109
133
}
110
134
}
@@ -149,6 +173,7 @@ export default defineComponent({
149
173
style = { {
150
174
marginTop : props . position === 'top' ? '0px' : '-16px' ,
151
175
top : suggestionsTop . value ? suggestionsTop . value + 'px' : 'inherit' ,
176
+ left : suggestionsLeft . value ? suggestionsLeft . value + 'px' : 'inherit' ,
152
177
} } >
153
178
{ filteredSuggestions . value . length > 0 ? (
154
179
filteredSuggestions . value ?. map ( ( item , index ) => {
0 commit comments