| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 | 
							- <template>
 
-   <div
 
-     class="el-autocomplete"
 
-     v-clickoutside="close"
 
-     aria-haspopup="listbox"
 
-     role="combobox"
 
-     :aria-expanded="suggestionVisible"
 
-     :aria-owns="id"
 
-   >
 
-     <el-input
 
-       ref="input"
 
-       v-bind="[$props, $attrs]"
 
-       @input="handleInput"
 
-       @change="handleChange"
 
-       @focus="handleFocus"
 
-       @blur="handleBlur"
 
-       @clear="handleClear"
 
-       @keydown.up.native.prevent="highlight(highlightedIndex - 1)"
 
-       @keydown.down.native.prevent="highlight(highlightedIndex + 1)"
 
-       @keydown.enter.native="handleKeyEnter"
 
-       @keydown.native.tab="close"
 
-     >
 
-       <template slot="prepend" v-if="$slots.prepend">
 
-         <slot name="prepend"></slot>
 
-       </template>
 
-       <template slot="append" v-if="$slots.append">
 
-         <slot name="append"></slot>
 
-       </template>
 
-       <template slot="prefix" v-if="$slots.prefix">
 
-         <slot name="prefix"></slot>
 
-       </template>
 
-       <template slot="suffix" v-if="$slots.suffix">
 
-         <slot name="suffix"></slot>
 
-       </template>
 
-     </el-input>
 
-     <el-autocomplete-suggestions
 
-       visible-arrow
 
-       :class="[popperClass ? popperClass : '']"
 
-       :popper-options="popperOptions"
 
-       :append-to-body="popperAppendToBody"
 
-       ref="suggestions"
 
-       :placement="placement"
 
-       :id="id">
 
-       <li
 
-         v-for="(item, index) in suggestions"
 
-         :key="index"
 
-         :class="{'highlighted': highlightedIndex === index}"
 
-         @click="select(item)"
 
-         :id="`${id}-item-${index}`"
 
-         role="option"
 
-         :aria-selected="highlightedIndex === index"
 
-       >
 
-         <slot :item="item">
 
-           {{ item[valueKey] }}
 
-         </slot>
 
-       </li>
 
-     </el-autocomplete-suggestions>
 
-   </div>
 
- </template>
 
- <script>
 
-   import debounce from 'throttle-debounce/debounce';
 
-   import ElInput from 'element-ui/packages/input';
 
-   import Clickoutside from 'element-ui/src/utils/clickoutside';
 
-   import ElAutocompleteSuggestions from './autocomplete-suggestions.vue';
 
-   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';
 
-   export default {
 
-     name: 'ElAutocomplete',
 
-     mixins: [Emitter, Focus('input'), Migrating],
 
-     inheritAttrs: false,
 
-     componentName: 'ElAutocomplete',
 
-     components: {
 
-       ElInput,
 
-       ElAutocompleteSuggestions
 
-     },
 
-     directives: { Clickoutside },
 
-     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() {
 
-       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: {
 
-       suggestionVisible(val) {
 
-         let $input = this.getInput();
 
-         if ($input) {
 
-           this.broadcast('ElAutocompleteSuggestions', 'visible', [val, $input.offsetWidth]);
 
-         }
 
-       }
 
-     },
 
-     methods: {
 
-       getMigratingConfig() {
 
-         return {
 
-           props: {
 
-             'custom-item': 'custom-item is removed, use scoped slot instead.',
 
-             'props': 'props is removed, use value-key instead.'
 
-           }
 
-         };
 
-       },
 
-       getData(queryString) {
 
-         if (this.suggestionDisabled) {
 
-           return;
 
-         }
 
-         this.loading = true;
 
-         this.fetchSuggestions(queryString, (suggestions) => {
 
-           this.loading = false;
 
-           if (this.suggestionDisabled) {
 
-             return;
 
-           }
 
-           if (Array.isArray(suggestions)) {
 
-             this.suggestions = suggestions;
 
-             this.highlightedIndex = this.highlightFirstItem ? 0 : -1;
 
-           } else {
 
-             console.error('[Element Error][Autocomplete]autocomplete suggestions must be an array');
 
-           }
 
-         });
 
-       },
 
-       handleInput(value) {
 
-         this.$emit('input', value);
 
-         this.suggestionDisabled = false;
 
-         if (!this.triggerOnFocus && !value) {
 
-           this.suggestionDisabled = true;
 
-           this.suggestions = [];
 
-           return;
 
-         }
 
-         this.debouncedGetData(value);
 
-       },
 
-       handleChange(value) {
 
-         this.$emit('change', value);
 
-       },
 
-       handleFocus(event) {
 
-         this.activated = true;
 
-         this.$emit('focus', event);
 
-         if (this.triggerOnFocus) {
 
-           this.debouncedGetData(this.value);
 
-         }
 
-       },
 
-       handleBlur(event) {
 
-         this.$emit('blur', event);
 
-       },
 
-       handleClear() {
 
-         this.activated = false;
 
-         this.$emit('clear');
 
-       },
 
-       close(e) {
 
-         this.activated = false;
 
-       },
 
-       handleKeyEnter(e) {
 
-         if (this.suggestionVisible && this.highlightedIndex >= 0 && this.highlightedIndex < this.suggestions.length) {
 
-           e.preventDefault();
 
-           this.select(this.suggestions[this.highlightedIndex]);
 
-         } else if (this.selectWhenUnmatched) {
 
-           this.$emit('select', {value: this.value});
 
-           this.$nextTick(_ => {
 
-             this.suggestions = [];
 
-             this.highlightedIndex = -1;
 
-           });
 
-         }
 
-       },
 
-       select(item) {
 
-         this.$emit('input', item[this.valueKey]);
 
-         this.$emit('select', item);
 
-         this.$nextTick(_ => {
 
-           this.suggestions = [];
 
-           this.highlightedIndex = -1;
 
-         });
 
-       },
 
-       highlight(index) {
 
-         if (!this.suggestionVisible || this.loading) { return; }
 
-         if (index < 0) {
 
-           this.highlightedIndex = -1;
 
-           return;
 
-         }
 
-         if (index >= this.suggestions.length) {
 
-           index = this.suggestions.length - 1;
 
-         }
 
-         const suggestion = this.$refs.suggestions.$el.querySelector('.el-autocomplete-suggestion__wrap');
 
-         const suggestionList = suggestion.querySelectorAll('.el-autocomplete-suggestion__list li');
 
-         let highlightItem = suggestionList[index];
 
-         let scrollTop = suggestion.scrollTop;
 
-         let offsetTop = highlightItem.offsetTop;
 
-         if (offsetTop + highlightItem.scrollHeight > (scrollTop + suggestion.clientHeight)) {
 
-           suggestion.scrollTop += highlightItem.scrollHeight;
 
-         }
 
-         if (offsetTop < scrollTop) {
 
-           suggestion.scrollTop -= highlightItem.scrollHeight;
 
-         }
 
-         this.highlightedIndex = index;
 
-         let $input = this.getInput();
 
-         $input.setAttribute('aria-activedescendant', `${this.id}-item-${this.highlightedIndex}`);
 
-       },
 
-       getInput() {
 
-         return this.$refs.input.getInput();
 
-       }
 
-     },
 
-     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}`);
 
-     },
 
-     beforeDestroy() {
 
-       this.$refs.suggestions.$destroy();
 
-     }
 
-   };
 
- </script>
 
 
  |