4040 :class ="multiple ? 'is-multiple' : 'is-single'"
4141 )
4242 input(
43+ ref ="input"
4344 v-model ="query"
4445 autocomplete ="off"
4546 @click.stop ="noop"
8788import throttle from ' lodash/throttle'
8889
8990import zIndex from ' @util/zIndexManager'
90- import { getPosition , POSITION } from ' ./position'
91+ import { getPosition } from ' ./position'
9192import resettable from ' @scripts/mixins/resettable'
9293import validatable from ' @scripts/mixins/validatable'
9394import PortalComponent from ' ../portal'
@@ -118,6 +119,10 @@ export default {
118119 type: String ,
119120 default: ' 请选择...'
120121 },
122+ shouldMenuOverlap: {
123+ type: Boolean ,
124+ default: true
125+ },
121126 multiple: Boolean ,
122127 combobox: Boolean ,
123128 autocomplete: Boolean ,
@@ -205,7 +210,7 @@ export default {
205210 },
206211 showPlaceholder () {
207212 const empty = ! this .selectedOptions .length
208- return empty && ! this .isOpen
213+ return empty && ! this .showInput
209214 },
210215 exceedMaxChipCount () {
211216 return this .selectedOptions .length > this .maxChipCount
@@ -225,7 +230,10 @@ export default {
225230 isOpen () {
226231 if (this .isOpen ) {
227232 this .menuStyle .minWidth = ` ${ this .$el .offsetWidth } px`
228- this .positionMenu ()
233+ // reset positon to next tick
234+ // this would fix cases where input element in `<c-select autocomplete />`
235+ // is expanding (add a new line)
236+ this .$nextTick (this .positionMenu )
229237 window .addEventListener (' click' , this .onBodyClick , true )
230238 } else {
231239 window .removeEventListener (' click' , this .onBodyClick , true )
@@ -248,9 +256,7 @@ export default {
248256
249257 selectedOptions : function () {
250258 if (! this .multiple || this .$isServer ) return
251- this .$nextTick (function () {
252- this .positionMenu ()
253- })
259+ this .$nextTick (this .positionMenu )
254260 }
255261 },
256262
@@ -354,14 +360,18 @@ export default {
354360 }
355361 },
356362
363+ focusOnInput () {
364+ this .$nextTick (() => {
365+ this .$refs .input .focus ()
366+ })
367+ },
368+
357369 open () {
358370 this .isOpen = true ;
359371 [this .activeOption ] = this .filteredOptions
360372 if (this .showInput ) {
361373 this .query = ' '
362- this .$nextTick (_ => {
363- this .$el .querySelector (' input' ).focus ()
364- })
374+ this .focusOnInput ()
365375 }
366376 },
367377
@@ -426,15 +436,20 @@ export default {
426436 const index = this .selectedOptions .indexOf (option)
427437 this .selectedOptions .splice (index, 1 )
428438 this .emitChange ()
439+ // 输入框重新获得焦点
440+ this .focusOnInput ()
429441 },
430442
431443 positionMenu () {
432- const pos = this .canInput ? POSITION .BOTTOM : POSITION .TOP
433- const { top , left } = getPosition (this .menuEl , this .$el , pos)
434- const { style } = this .menuEl
435- style .top = ` ${ top} px`
436- style .left = ` ${ left} px`
437- style .zIndex = zIndex .next ()
444+ const { shouldMenuOverlap , canInput , menuEl } = this
445+ const { top , left , height } = getPosition (menuEl, this .$el )
446+ const overlap = shouldMenuOverlap && ! canInput
447+
448+ const offset = 4
449+ const menuTop = overlap ? top : (top + height + offset)
450+ menuEl .style .left = ` ${ left} px`
451+ menuEl .style .top = ` ${ menuTop} px`
452+ menuEl .style .zIndex = zIndex .next ()
438453 },
439454
440455 onBodyClick (e ) {
0 commit comments