Sfoglia il codice sorgente

insert autocomplete suggestions to body

baiyaaaaa 8 anni fa
parent
commit
3c0a784aca

+ 20 - 19
examples/docs/en-US/input.md

@@ -117,23 +117,23 @@
         text-align: left;
       }
     }
-    .my-autocomplete {
-      li {
-        line-height: normal;
-        padding: 7px *;
-
-        .name {
-          text-overflow: ellipsis;
-          overflow: hidden;
-        }
-        .addr {
-          font-size: 12px;
-          color: #b4b4b4;
-        }
-
-        .highlighted .addr {
-          color: #ddd;
-        }
+  }
+  .el-autocomplete__suggestions.my-autocomplete {
+    li {
+      line-height: normal;
+      padding: 7px *;
+
+      .name {
+        text-overflow: ellipsis;
+        overflow: hidden;
+      }
+      .addr {
+        font-size: 12px;
+        color: #b4b4b4;
+      }
+
+      .highlighted .addr {
+        color: #ddd;
       }
     }
   }
@@ -326,7 +326,7 @@ export default {
 ```
 :::
 
-### Auto complete
+### Autocomplete
 
 You can get some recommended tips based on the current input.
 
@@ -406,7 +406,7 @@ Customize how suggestions are displayed.
 :::demo
 ```html
 <el-autocomplete
-  class="my-autocomplete"
+  popper-class="my-autocomplete"
   v-model="state3"
   :fetch-suggestions="querySearch"
   custom-item="my-item-en"
@@ -587,6 +587,7 @@ Attribute | Description | Type | Options | Default
 |value | binding value | string | — | — |
 |custom-item | component name of your customized suggestion list item | string | — | — |
 |fetch-suggestions | a method to fetch input suggestions. When suggestions are ready, invoke `callback(data:[])` to return them to Autocomplete | Function(queryString, callback) | — | — |
+| popper-class | custom class name for autocomplete's dropdown | string | — | — |
 
 ### Autocomplete Events
 

+ 19 - 18
examples/docs/zh-CN/input.md

@@ -158,23 +158,23 @@
         text-align: left;
       }
     }
-    .my-autocomplete {
-      li {
-        line-height: normal;
-        padding: 7px *;
-
-        .name {
-          text-overflow: ellipsis;
-          overflow: hidden;
-        }
-        .addr {
-          font-size: 12px;
-          color: #b4b4b4;
-        }
-
-        .highlighted .addr {
-          color: #ddd;
-        }
+  }
+  .el-autocomplete__suggestions.my-autocomplete {
+    li {
+      line-height: normal;
+      padding: 7px *;
+
+      .name {
+        text-overflow: ellipsis;
+        overflow: hidden;
+      }
+      .addr {
+        font-size: 12px;
+        color: #b4b4b4;
+      }
+
+      .highlighted .addr {
+        color: #ddd;
       }
     }
   }
@@ -483,7 +483,7 @@ export default {
 ::: demo
 ```html
 <el-autocomplete
-  class="my-autocomplete"
+  popper-class="my-autocomplete"
   v-model="state3"
   :fetch-suggestions="querySearch"
   custom-item="my-item-zh"
@@ -748,6 +748,7 @@ export default {
 | value         | 必填值输入绑定值   | string  | — | — |
 | custom-item  | 通过该参数指定自定义的输入建议列表项的组件名 | string  | — | — |
 | fetch-suggestions | 返回输入建议的方法,仅当你的输入建议数据 resolve 时,通过调用 callback(data:[]) 来返回它  | Function(queryString, callback)  | — | — |
+| popper-class | Autocomplete 下拉列表的类名 | string | — | — |
 
 ### Autocomplete Events
 | 事件名称 | 说明 | 回调参数 |

+ 68 - 0
packages/autocomplete/src/autocomplete-suggestions.vue

@@ -0,0 +1,68 @@
+<template>
+  <transition name="el-zoom-in-top" @after-leave="doDestroy">
+    <ul
+      v-show="showPopper"
+      class="el-autocomplete__suggestions"
+      :class="{ 'is-loading': parent.loading }"
+      :style="{ width: dropdownWidth }"
+    >
+      <li v-if="parent.loading"><i class="el-icon-loading"></i></li>
+      <template v-for="(item, index) in suggestions" v-else>
+        <li
+          v-if="!parent.customItem"
+          :class="{'highlighted': parent.highlightedIndex === index}"
+          @click="parent.select(index)"
+        >
+          {{item.value}}
+        </li>
+        <component
+          v-else
+          :class="{'highlighted': parent.highlightedIndex === index}"
+          @click="parent.select(index)"
+          :is="parent.customItem"
+          :item="item"
+          :index="index">
+        </component>
+      </template>
+    </ul>
+  </transition>
+</template>
+<script>
+  import Popper from 'element-ui/src/utils/vue-popper';
+  export default {
+    mixins: [Popper],
+
+    componentName: 'ElAutocompleteSuggestions',
+
+    data() {
+      return {
+        parent: this.$parent,
+        dropdownWidth: ''
+      };
+    },
+
+    props: {
+      suggestions: Array,
+      options: {
+        default() {
+          return {
+            forceAbsolute: true,
+            gpuAcceleration: false
+          };
+        }
+      }
+    },
+
+    mounted() {
+      this.popperElm = this.$el;
+      this.referenceElm = this.$parent.$el;
+    },
+
+    created() {
+      this.$on('visible', (val, inputWidth) => {
+        this.dropdownWidth = inputWidth + 'px';
+        this.showPopper = val;
+      });
+    }
+  };
+</script>

+ 23 - 32
packages/autocomplete/src/autocomplete.vue

@@ -19,47 +19,34 @@
         <slot name="append"></slot>
       </template> 
     </el-input>
-    <transition name="el-zoom-in-top">
-      <ul
-        v-if="suggestionVisible"
-        class="el-autocomplete__suggestions"
-        :class="{ 'is-loading': loading }"
-        ref="suggestions"
-      >
-        <li v-if="loading"><i class="el-icon-loading"></i></li>
-        <template v-for="(item, index) in suggestions" v-else>
-          <li
-            v-if="!customItem"
-            :class="{'highlighted': highlightedIndex === index}"
-            @click="select(index)"
-          >
-            {{item.value}}
-          </li>
-          <component
-            v-else
-            :class="{'highlighted': highlightedIndex === index}"
-            @click="select(index)"
-            :is="customItem"
-            :item="item"
-            :index="index">
-          </component>
-        </template>
-      </ul>
-    </transition>
+    <el-autocomplete-suggestions
+      :class="[popperClass ? popperClass : '']"
+      ref="suggestions"
+      :suggestions="suggestions"
+    >
+    </el-autocomplete-suggestions>
   </div>
 </template>
 <script>
   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';
 
   export default {
     name: 'ElAutocomplete',
 
+    mixins: [Emitter],
+
     components: {
-      ElInput
+      ElInput,
+      ElAutocompleteSuggestions
     },
+
     directives: { Clickoutside },
+
     props: {
+      popperClass: String,
       placeholder: String,
       disabled: Boolean,
       name: String,
@@ -80,8 +67,10 @@
         highlightedIndex: -1
       };
     },
-    mounted() {
-      this.$parent.popperElm = this.popperElm = this.$el;
+    watch: {
+      suggestionVisible(val) {
+        this.broadcast('ElAutocompleteSuggestions', 'visible', [val, this.$el.offsetWidth]);
+      }
     },
     methods: {
       handleChange(value) {
@@ -107,7 +96,6 @@
       },
       hideSuggestions() {
         this.suggestionVisible = false;
-        this.suggestions = [];
         this.loading = false;
       },
       showSuggestions(value) {
@@ -129,8 +117,8 @@
         } else if (index >= this.suggestions.length) {
           index = this.suggestions.length - 1;
         }
+        var elSuggestions = this.$refs.suggestions.$el;
 
-        var elSuggestions = this.$refs.suggestions;
         var elSelect = elSuggestions.children[index];
         var scrollTop = elSuggestions.scrollTop;
         var offsetTop = elSelect.offsetTop;
@@ -144,6 +132,9 @@
 
         this.highlightedIndex = index;
       }
+    },
+    beforeDestroy() {
+      this.$refs.suggestions.$destroy();
     }
   };
 </script>

+ 1 - 1
packages/theme-default/src/autocomplete.css

@@ -11,7 +11,7 @@
       position: absolute;
       left: 0;
       top: 110%;
-      margin: 0;
+      margin: 5px 0 0;
       background-color: #fff;
       border: 1px solid #D3DCE6;
       width: 100%;

+ 8 - 6
test/unit/specs/autocomplete.spec.js

@@ -9,6 +9,7 @@ describe('Autocomplete', () => {
     vm = createVue({
       template: `
         <el-autocomplete
+          ref="autocomplete"
           v-model="state"
           :fetch-suggestions="querySearch"
           placeholder="请输入内容autocomplete1"
@@ -51,12 +52,12 @@ describe('Autocomplete', () => {
     expect(inputElm.getAttribute('placeholder')).to.be.equal('请输入内容autocomplete1');
 
     setTimeout(_ => {
-      let suggestionsList = elm.querySelector('.el-autocomplete__suggestions');
-      expect(suggestionsList).to.exist;
+      let suggestionsList = vm.$refs.autocomplete.$refs.suggestions.$el;
+      expect(suggestionsList.style.display).to.not.equal('none');
       expect(suggestionsList.children.length).to.be.equal(4);
       document.body.click();
       setTimeout(_ => {
-        expect(elm.querySelector('.el-autocomplete__suggestions')).to.not.exist;
+        expect(document.querySelector('.el-autocomplete__suggestions').style.display).to.be.equal('none');
         done();
       }, 500);
     }, 500);
@@ -66,6 +67,7 @@ describe('Autocomplete', () => {
       template: `
         <el-autocomplete
           v-model="state"
+          ref="autocomplete"
           :fetch-suggestions="querySearch"
           placeholder="请输入内容autocomplete2"
           @select="handleSelect"
@@ -110,7 +112,7 @@ describe('Autocomplete', () => {
     inputElm.focus();
 
     setTimeout(_ => {
-      let suggestionsList = elm.querySelector('.el-autocomplete__suggestions');
+      let suggestionsList = vm.$refs.autocomplete.$refs.suggestions.$el;
       suggestionsList.children[1].click();
       setTimeout(_ => {
         expect(inputElm.value).to.be.equal('Hot honey 首尔炸鸡(仙霞路)');
@@ -191,7 +193,7 @@ describe('Autocomplete', () => {
     setTimeout(_ => {
       vm.$refs.autocomplete.highlight(8);
       vm.$nextTick(_ => {
-        let suggestionsList = elm.querySelector('.el-autocomplete__suggestions');
+        let suggestionsList = vm.$refs.autocomplete.$refs.suggestions.$el;
         let highlightedItem = suggestionsList.children[8];
         expect(highlightedItem.className).to.be.equal('highlighted');
         expect(suggestionsList.scrollTop === highlightedItem.scrollHeight).to.be.true;
@@ -261,7 +263,7 @@ describe('Autocomplete', () => {
     setTimeout(_ => {
       vm.$refs.autocomplete.highlight(15);
       vm.$nextTick(_ => {
-        let suggestionsList = elm.querySelector('.el-autocomplete__suggestions');
+        let suggestionsList = vm.$refs.autocomplete.$refs.suggestions.$el;
         let highlightedItem = suggestionsList.children[11];
         expect(highlightedItem.className).to.be.equal('highlighted');