element原始碼解析(2) -- autocomplete
阿新 • • 發佈:2021-01-24
技術標籤:element ui
autocomplete原始碼解析
autocomplete中包含三個元件,input和suggestion/el-scrollbar
template
一個class:
el-autocomplete:相對定位和行內塊;
一個自定義指令:v-clickoutside:點選此dom元素外觸發事件
el-input
四個emit觸發事件:input,focus,blur,clear調節顯示隱藏高亮清除
四個鍵盤事件up,down,enter,tab
四個插槽:prepend,append,prefix,suffix
v-bind="[$props, $attrs]",v-bind可用陣列/物件,說明接收所有跟input相關的屬性
el-autocomplete-suggestions
visible-arrow:沒見到這個屬性發揮作用
四個屬性:
:popper-options=“popperOptions”
預設無
:append-to-body=“popperAppendToBody”
popperAppendToBody: {
type: Boolean,
default: true
},
:placement=“placement”:
預設正下方
placement: {
type: String,
default: 'bottom-start'
},
:id=“id”
生成id隨機數
export const generateId = function(){
return Math.floor(Math.random() * 10000)
}
popperClass:
屬於自定義autocomplete-suggestions的class
script
引入防抖函式,外部點選指令,
混入廣播派發事件,獲取焦點方法Focus(‘input’)
Migrating 生產中沒有用處,開發中可以給提示警告
import debounce from 'throttle-debounce/debounce';
import Clickoutside from 'element-ui/src/utils/clickoutside';
import Emitter from 'element-ui/src/mixins/emitter';
import Migrating from 'element-ui/src/mixins/migrating';
import { generateId } from 'element-ui/src/utils/util';
import Focus from 'element-ui/src/mixins/focus';
props
24個屬性
- valueKey: 預設為value,取list中的key,輸入建議物件中用於顯示的鍵名
- popperClass:Autocomplete 下拉列表的類名
- popperOptions:暫時沒用上,應該與vue-popper選項有關
- placeholoder: 輸入框佔位文字
- clearable:是否清除,預設不顯示
- disabled:是否禁用,預設不禁用
- name:原生屬性,input的name,在v-bind中實現
- size:沒見著怎麼用
- value:給預設值
- maxlength:最大數量
- minlength:最小數量
- autofocus:是否自動獲取焦點
- fetchSuggestions:可以沒有queryString,必須回撥,回撥必須帶引數,引數就是suggestions的結果,用意自然是可以去根據queryString去做過濾,但其實直接傳過濾後的資料不香嗎,繞得不太好.
- triggerOnFocus:是否在輸入框focus的時候給出建議列表,預設為true,獲取焦點的時候去判斷
- customItem:沒發現用到
- selectWhenUnmatched:預設為false,enter的時候觸發,不匹配,清空
- prefixIcon:el-input的屬性
- suffixIcon:el-input的屬性
- label:el-input屬性
- debounce:防抖時間
- placement:建議列表位置
- hideLoading:是否隱藏loading
- popperAppendToBody:彈框是否依附於body,預設依附,否則插入
- highlightFirstItem:是否預設突出顯示遠端搜尋建議中的第一項
handleFocus(event) {
this.activated = true;
this.$emit('focus', event);
if (this.triggerOnFocus) {
this.debouncedGetData(this.value);
}
},
props: {
valueKey: {
type: String,
default: 'value'
},
popperClass: String,
popperOptions: Object,
placeholder: String,
clearable: {
type: Boolean,
default: false
},
disabled: Boolean,
name: String,
size: String,
value: String,
maxlength: Number,
minlength: Number,
autofocus: Boolean,
fetchSuggestions: Function,
triggerOnFocus: {
type: Boolean,
default: true
},
customItem: String,
selectWhenUnmatched: {
type: Boolean,
default: false
},
prefixIcon: String,
suffixIcon: String,
label: String,
debounce: {
type: Number,
default: 300
},
placement: {
type: String,
default: 'bottom-start'
},
hideLoading: Boolean,
popperAppendToBody: {
type: Boolean,
default: true
},
highlightFirstItem: {
type: Boolean,
default: false
}
},
data
五個自定義變數
actived表示獲取焦點時為true,啟用搜尋建議
suggestions建議列表的資料
loading預設沒有載入
highlightedIndex:表示高亮的選項
suggestionDisabled:表示禁用
data() {
return {
activated: false,
suggestions: [],
loading: false,
highlightedIndex: -1,
suggestionDisabled: false
};
},
computed
計算屬性:
如果資料發生變化,則根據當前判斷是否啟用狀態,根據是否有資料來顯示隱藏:
suggestionVisible() {
const suggestions = this.suggestions;
let isValidData = Array.isArray(suggestions) && suggestions.length > 0;
return (isValidData || this.loading) && this.activated;
},
id() {
return `el-autocomplete-${generateId()}`;
}
watch
監聽,如果可見性發生變化,直接給子元件派發事件,告訴子元件值和寬度
watch: {
suggestionVisible(val) {
let $input = this.getInput();
if ($input) {
this.broadcast('ElAutocompleteSuggestions', 'visible', [val, $input.offsetWidth]);
}
}
},
mounted
this.debouncedGetData = debounce(this.debounce, this.getData);
this.$on('item-click', item => {
this.select(item);
});
let $input = this.getInput();
$input.setAttribute('role', 'textbox');
$input.setAttribute('aria-autocomplete', 'list');
$input.setAttribute('aria-controls', 'id');
$input.setAttribute('aria-activedescendant', `${this.id}-item-${this.highlightedIndex}`);