Vue.js 帶下拉選項的輸入框(Textbox with Dropdown)組件
- 2021 年 4 月 14 日
- 筆記
- javascript, VUE
帶下拉選項的輸入框 (Textbox with Dropdown) 是既允許用戶從下拉列表中選擇輸入又允許用戶自由鍵入輸入值。這算是比較常見的一種 UI 元素,可以為用戶提供候選項節省操作時間,也可以給可能存在的少數情況提供適配的可能。
本來想着這個組件比較常見應該已經有比較多現成的例子可以直接應用,但是搜索了一圈發現很多類似的組件都具備了太多的功能,例如搜索,多選等等 (簡單說:太複雜了!)。於是就想着還是自己動手寫一個簡單易用的,此處要感謝肥老闆在我困惑時的鼎力相助。
這個 UI 元素將被用於 Common Bar Width App 中。
註冊組件
通過將封裝好的組件代碼複製粘貼來註冊全局組件。
設計的時候有考慮到輸入框可能存在不同的類型,例如文本輸入框,數值輸入框,百分數輸入框等等。所以在封裝的代碼中會通過函數 inputRule
來限制輸入。限制的方法是利用 Regex 進行過濾。如果有其他類型,也可以通過修改 inputRule
中的過濾條件。
<script type="text/x-template" id="dropdown">
<div class="dropdown" v-if="options">
<!-- Dropdown Input -->
<input :type="type"
:disabled="disabled"
v-model="input_value"
@focus="showOptions()"
@blur="exit()"
@keyup="keyMonitor"
@input="input_value = inputRule(type)" />
...
</script>
<script>
Vue.component('dropdown', {
template: '#dropdown',
props: {
type: String,
options: Array,
disabled: Boolean,
value: String
},
...
methods: {
inputRule:function(type){
var value;
switch(type){
case 'text':
value = this.input_value.replace(/[^a-zA-Z0-9]/g,'');
break;
case 'number':
value = this.input_value.replace(/^(?![+-]?\d+(\.\d+)?$)/g,'');
break;
case 'percentage':
value = this.input_value.replace(/[^\d]/g,'');
value = value > 100 ? '100' : value;
value = value < 0 ? '0' : value;
break;
default:
console.log("no limitation");
}
return value;
},
...
</script>
調用組件
添加自定義標籤調用組件。
<dropdown type = "text"
:options = "text_options"
:value = "text_value"
:disabled = "text_disabled"
@on_change_input_value = "onTextChange">
</dropdown>
傳遞數據
最後動態綁定數據到父級組件, props 中:
- type: 輸入框的類型,現支持 text, number 和 percentage。
- options: 輸入框下拉列表的選項
- value: 輸入框的值
- disabled: 是否禁止點擊輸入框
另外我們還需要在父級實例中定義事情,用於更新輸入框的值
- on_change_input_value: 更新值
data: function () {
return {
text_value: 'ccc',
text_disabled: false,
text_options: [
{ id: 1, name: 'a' },
{ id: 2, name: 'bb' },
{ id: 3, name: 'ccc' },
{ id: 4, name: 'dddd' },
{ id: 5, name: 'eeeee' },
{ id: 6, name: 'fffff ' },
{ id: 7, name: 'gggggg' },
{ id: 8, name: 'hhhhhhh' },
{ id: 9, name: 'iiiiiiii' },
],
...
}
},
...
methods: {
onTextChange: function (new_text_value) {
this.text_value = new_text_value;
},
...
},