2022年4月19日 星期二

Vue-multiselect 學習心得

基本用法

html
====
<vue-multiselect style="width:7em;" v-model="居住城市" :options="居住城市s" :multiple="true" :close-on-select="false" :clear-on-select="false" placeholder="居住地區" label="text" track-by="value" select-label="" selected-label="" deselect-label="" limit="1" :limit-text="limitText" :title="已選擇居住城市">                  
</vue-multiselect>      

javascript
====
已選擇居住城市() {
  let text = "";
  if (this.居住城市) this.居住城市.forEach(a => text += "、" + a.text);
  return text.substring(1);
},
limitText(count) {
  return `已選擇 ${count+1}`;
},  

css
====
.multiselect {
    display: inline-block;
    min-height: unset;
    color: unset;
}

.multiselect--disabled {
    opacity: unset;
    
}
    .multiselect--disabled .multiselect__select {
        background-color: #fff;
    }
    .multiselect input, .multiselect__single {
        font-size: inherit;
    }

.multiselect__single {
    margin-top: 2px;
    margin-bottom: 3px;
    padding-left: 0;
}

.multiselect__input {
    width: 5em !important;
    padding-left: 0;
}

.multiselect__option {
    padding: 5px;
    min-height: unset;
}

.multiselect__option--selected {
    background-color: yellow;
}

.multiselect__option:after {
    padding-right: 5px;
    line-height: unset;
    top: 5px;
    font-size: unset;
}

.multiselect__select {
    width: 20px;
    height: 35px;
    padding: unset;
}

.multiselect__tags {
    padding: 5px 20px 0 5px;
    min-height: 35px;
}
.multiselect__input {
    padding: 2px 0 0 0;
    margin-bottom:0;
}

.multiselect__tag {
    margin: 0;
    padding-left: 3px;
    padding-right: 15px;
}

.multiselect__tag-icon {
    width: 15px;
}

.multiselect__strong {
    margin-bottom: unset;
}

.multiselect__content-wrapper, .multiselect--active {
    z-index: 6 !important; // 避免下拉選單被遮住,但一樣會被 b-table sticky column 遮住且無解!
}

.multiselect__content-wrapper {
    width: unset;
    min-width: 100%;
}

輸入關鍵字即時呼叫後端取得資料

html
====
<vue-multiselect :ref="xxx" :id="xxx" v-model="item" label="text" track-by="value" placeholder="輸入姓名" open-direction="bottom" :options="items" :searchable="true" select-label="" selected-label="" deselect-label="" :internal-search="false" :options-limit="30" v-on:search-change="findSender($event,xxx)">
    <span slot="noResult">查無資料</span>
</vue-multiselect>

javascript
====
findSender(searchtext, id) {
            if (searchtext.length < 2) return;
            // 延遲且單一處理(丟棄尚未啟動的呼叫),避免輸入太快造成先發後至錯亂問
            clearTimeout(this.$_timeout);
            this.$_timeout = setTimeout(() => { 題
                this.items = [];
                this.item = null;
                let $vue = this;
                axios.post(..., { text: searchtext})
                    .then(response => {
                        if (response.data.length > 0) {
                            $vue.items = response.data.map(a => ({ value: a.value, text: a.name }));
                        }
                    }).catch(function (error) {
                        console.error(error);
                        $vue.$bvToast.toast(error.response.data, { variant: 'danger', solid: true, noAutoHide: true });
                    });
            }, 500); // set this value to your preferred debounce timeout
        },

取得對應的dom 進行其他操作
$(this.$refs.xxx.$el).closest('tr').find('[name=...]').focus();

關閉選單
this.$refs.xxx.deactivate();

input 連結 datalist 用程式控制彈出選項

範例: nextTick(() => document.querySelector('input').showPicker());  ※僅支援現代瀏覽器