Commit 3e855e34df94d586c7d3ebbd7c59cb12f5a0f49d

Authored by 梁灏
1 parent f94309af

fixed #46

fixed #46
src/components/select/select.vue
... ... @@ -26,7 +26,7 @@
26 26 </div>
27 27 <Dropdown v-show="visible" transition="slide-up" v-ref:dropdown>
28 28 <ul v-show="notFound" :class="[prefixCls + '-not-found']"><li>{{ notFoundText }}</li></ul>
29   - <ul v-else :class="[prefixCls + '-dropdown-list']"><slot></slot></ul>
  29 + <ul v-else :class="[prefixCls + '-dropdown-list']" v-el:options><slot></slot></ul>
30 30 </Dropdown>
31 31 </div>
32 32 </template>
... ... @@ -34,7 +34,7 @@
34 34 import Icon from '../icon';
35 35 import Dropdown from './dropdown.vue';
36 36 import clickoutside from '../../directives/clickoutside';
37   - import { oneOf } from '../../utils/assist';
  37 + import { oneOf, MutationObserver } from '../../utils/assist';
38 38  
39 39 const prefixCls = 'ivu-select';
40 40  
... ... @@ -94,7 +94,8 @@
94 94 focusIndex: 0,
95 95 query: '',
96 96 inputLength: 20,
97   - notFound: false
  97 + notFound: false,
  98 + slotChangeDuration: false // if slot change duration and in multiple, set true and after slot change, set false
98 99 }
99 100 },
100 101 computed: {
... ... @@ -180,7 +181,7 @@
180 181 });
181 182 }
182 183 },
183   - updateOptions (init) {
  184 + updateOptions (init, slot = false) {
184 185 let options = [];
185 186 let index = 1;
186 187  
... ... @@ -199,20 +200,28 @@
199 200 this.options = options;
200 201  
201 202 if (init) {
202   - this.updateSingleSelected(true);
203   - this.updateMultipleSelected(true);
  203 + this.updateSingleSelected(true, slot);
  204 + this.updateMultipleSelected(true, slot);
204 205 }
205 206 },
206   - updateSingleSelected (init = false) {
  207 + updateSingleSelected (init = false, slot = false) {
207 208 const type = typeof this.model;
208 209  
209 210 if (type === 'string' || type === 'number') {
  211 + let findModel = false;
  212 +
210 213 for (let i = 0; i < this.options.length; i++) {
211 214 if (this.model === this.options[i].value) {
212 215 this.selectedSingle = this.options[i].label;
  216 + findModel = true;
213 217 break;
214 218 }
215 219 }
  220 +
  221 + if (slot && !findModel) {
  222 + this.model = '';
  223 + this.query = '';
  224 + }
216 225 }
217 226  
218 227 this.toggleSingleSelected(this.model, init);
... ... @@ -229,7 +238,7 @@
229 238 }
230 239 }
231 240 },
232   - updateMultipleSelected (init = false) {
  241 + updateMultipleSelected (init = false, slot = false) {
233 242 if (this.multiple && Array.isArray(this.model)) {
234 243 let selected = [];
235 244  
... ... @@ -249,8 +258,22 @@
249 258 }
250 259  
251 260 this.selectedMultiple = selected;
252   - }
253 261  
  262 + if (slot) {
  263 + let selectedModel = [];
  264 +
  265 + for (let i = 0; i < selected.length; i++) {
  266 + selectedModel.push(selected[i].value);
  267 + }
  268 +
  269 + // if slot change and remove a selected option, emit user
  270 + if (this.model.length === selectedModel.length) {
  271 + this.slotChangeDuration = true;
  272 + }
  273 +
  274 + this.model = selectedModel;
  275 + }
  276 + }
254 277 this.toggleMultipleSelected(this.model, init);
255 278 },
256 279 removeTag (index) {
... ... @@ -431,19 +454,46 @@
431 454 if (this.multiple && this.model.length && this.query === '') {
432 455 this.removeTag(this.model.length - 1);
433 456 }
  457 + },
  458 + // use when slot changed
  459 + slotChange () {
  460 + this.options = [];
  461 + this.optionInstances = [];
434 462 }
435 463 },
436 464 ready () {
437 465 this.updateOptions(true);
438 466 document.addEventListener('keydown', this.handleKeydown);
  467 +
  468 + // watch slot changed
  469 + if (MutationObserver) {
  470 + this.observer = new MutationObserver(() => {
  471 + this.slotChange();
  472 + this.updateOptions(true, true);
  473 + });
  474 +
  475 + this.observer.observe(this.$els.options, {
  476 +// attributes: true,
  477 + childList: true,
  478 + characterData: true,
  479 + subtree: true
  480 + });
  481 + }
439 482 },
440 483 beforeDestroy () {
441 484 document.removeEventListener('keydown', this.handleKeydown);
  485 + if (this.observer) {
  486 + this.observer.disconnect();
  487 + }
442 488 },
443 489 watch: {
444 490 model () {
445 491 if (this.multiple) {
446   - this.updateMultipleSelected();
  492 + if (this.slotChangeDuration) {
  493 + this.slotChangeDuration = false;
  494 + } else {
  495 + this.updateMultipleSelected();
  496 + }
447 497 } else {
448 498 this.updateSingleSelected();
449 499 }
... ...
src/styles/themes/default/custom.less
... ... @@ -46,7 +46,7 @@
46 46 @shadow-right : 1px 0 6px @shadow-color;
47 47  
48 48 // Button
49   -@btn-font-weight : 400;
  49 +@btn-font-weight : normal;
50 50 @btn-padding-base : 4px 15px;
51 51 @btn-padding-large : 6px 15px 7px 15px;
52 52 @btn-padding-small : 2px 7px;
... ...
src/utils/assist.js
... ... @@ -49,4 +49,7 @@ export function getScrollBarSize (fresh) {
49 49 cached = widthContained - widthScroll;
50 50 }
51 51 return cached;
52   -}
53 52 \ No newline at end of file
  53 +}
  54 +
  55 +// watch DOM change
  56 +export const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver || false;
54 57 \ No newline at end of file
... ...
test/routers/select.vue
1 1 <template>
2   - <div>
3   - <br><br><br><br><br><br><br><br><br><br><br>
4   - {{ city | json }}<br>
5   - <Button @click="city = 'hangzhou'">切换城市</Button>
6   - <br>
7   - <i-select v-if="true" :model.sync="city" style="width:200px" filterable @on-change="change">
8   - <i-option-group label="热门城市">
9   - <i-option value="beijing">北京市</i-option>
10   - <i-option value="shanghai" disabled label="上海市">上海市2</i-option>
11   - <i-option value="shenzhen">深圳市</i-option>
12   - </i-option-group>
13   - <i-option-group label="二线城市">
14   - <i-option value="nanjing">南京市</i-option>
15   - <i-option value="hangzhou">杭州市</i-option>
16   - <i-option value="heilongjiang" disabled>黑龙江市</i-option>
17   - </i-option-group>
18   - <i-option-group label="其它城市">
19   - <i-option value="jyg">嘉峪关市</i-option>
20   - <i-option value="lanzhou">兰州市</i-option>
21   - <i-option value="beijingxi">北京西</i-option>
22   - </i-option-group>
23   - </i-select>
24   -
25   - <i-select v-show="true" :model.sync="focus" style="width:200px" @on-change="change" clearable filterable label-in-value>
26   - <i-option value="beijing">北京</i-option>
27   - <i-option value="shanghai" label="上海市">上海市</i-option>
28   - <i-option value="shenzhen" disabled>深圳市</i-option>
29   - <i-option value="guangzhou" label="广州市">广州市2</i-option>
30   - <i-option value="shijiazhuang" disabled>石家庄市</i-option>
31   - <!--<i-option value="shijiazhuang2">石家庄市2</i-option>-->
32   - <i-option value="a">a市</i-option>
33   - <i-option value="b">b市</i-option>
34   - <i-option value="c">c市</i-option>
35   - <i-option value="d">d市</i-option>
36   - <i-option value="e">e市</i-option>
37   - </i-select>
38   -
39   - <i-select v-if="true" :model.sync="focus2" style="width:300px" @on-change="change" clearable filterable multiple>
40   - <i-option value="beijing" label="北京市">北京2</i-option>
41   - <i-option value="shanghai">上海市</i-option>
42   - <i-option value="shenzhen" disabled>深圳市</i-option>
43   - <i-option value="guangzhou">广州市</i-option>
44   - <i-option value="shijiazhuang">石家庄市</i-option>
45   - <i-option value="a">a1市</i-option>
46   - <i-option value="b">b2市</i-option>
47   - <i-option value="c">c1市</i-option>
48   - <i-option value="d">d2市</i-option>
49   - <i-option value="e">e1市</i-option>
50   - </i-select>
51   -
52   - <i-select v-if="true" :model.sync="focus2" style="width:300px" @on-change="change" clearable multiple>
53   - <i-option value="beijing" label="北京市">北京2</i-option>
54   - <i-option value="shanghai">上海市</i-option>
55   - <i-option value="shenzhen" disabled>深圳市</i-option>
56   - <i-option value="guangzhou">广州市</i-option>
57   - <i-option value="shijiazhuang">石家庄市</i-option>
58   - <i-option value="a">a市</i-option>
59   - <i-option value="b">b市</i-option>
60   - <i-option value="c">c市</i-option>
61   - <i-option value="d">d市</i-option>
62   - <i-option value="e">e市</i-option>
63   - </i-select>
64   -
65   - <br><br><br><br><br><br><br><br><br><br><br><br>
66   - </div>
  2 + <!--<i-select :model.sync="model1" style="width:200px">-->
  3 + <!--<i-option v-for="item in cityList" :value="item.value">{{ item.label }}</i-option>-->
  4 + <!--</i-select>-->
  5 + <!--{{ model1 | json }}-->
  6 + <i-button @click="change">修改数据</i-button>
  7 + <!--<i-select :model.sync="model10" multiple style="width:240px" @on-change="datachange">-->
  8 + <!--<i-option v-for="item in cityList" :value="item.value">{{ item.label }}</i-option>-->
  9 + <!--</i-select>-->
  10 + <!--{{ model10 | json }}-->
  11 + <!--<i-select :model.sync="model11" filterable style="width:200px" @on-change="datachange">-->
  12 + <!--<i-option v-for="item in cityList" :value="item.value">{{ item.label }}</i-option>-->
  13 + <!--</i-select>-->
  14 + <!--{{ model11 | json }}-->
  15 + <i-select :model.sync="model12" filterable multiple style="width:240px" @on-change="datachange">
  16 + <i-option v-for="item in cityList" :value="item.value">{{ item.label }}</i-option>
  17 + </i-select>
  18 + {{ model12 | json }}
67 19 </template>
68 20 <script>
69   - import { iSelect, iOption, iOptionGroup, Button } from 'iview';
70   -
  21 + import { iSelect, iOption, iButton } from 'iview';
71 22 export default {
72   - components: {
73   - iSelect,
74   - iOption,
75   - iOptionGroup,
76   - Button
77   - },
78   - props: {
79   -
80   - },
  23 + components: { iSelect, iOption, iButton },
81 24 data () {
82 25 return {
83   - city: '',
84   - focus: '',
85   - focus2: ['beijing']
86   -// focus2: []
  26 + cityList: [
  27 + {
  28 + value: 'beijing',
  29 + label: '北京市'
  30 + },
  31 + {
  32 + value: 'shanghai',
  33 + label: '上海市'
  34 + },
  35 + {
  36 + value: 'shenzhen',
  37 + label: '深圳市'
  38 + },
  39 + {
  40 + value: 'hangzhou',
  41 + label: '杭州市'
  42 + },
  43 + {
  44 + value: 'nanjing',
  45 + label: '南京市'
  46 + },
  47 + {
  48 + value: 'chongqing',
  49 + label: '重庆市'
  50 + }
  51 + ],
  52 + model1: '',
  53 + model10: [],
  54 + model11: '',
  55 + model12: []
87 56 }
88 57 },
89   - computed: {
90   -
91   - },
92 58 methods: {
93   - change (data) {
94   - console.log(data)
  59 + change () {
  60 + this.cityList.splice(2, 1);
  61 + },
  62 + datachange (data) {
  63 + console.log(data);
95 64 }
96 65 }
97 66 }
98   -</script>
99 67 \ No newline at end of file
  68 +</script>
... ...
test/routers/tag.vue
... ... @@ -28,10 +28,23 @@
28 28 <Tag type="border" color="red" closable>标签一</Tag>
29 29 <Tag type="border" color="yellow">标签一</Tag>
30 30 <Tag type="border" color="yellow" closable>标签一</Tag>
  31 + <i-button type="primary" @click="modal1 = true">显示对话框</i-button>
  32 + <Modal
  33 + :visible.sync="modal1"
  34 + title="普通的Modal对话框标题">
  35 + <p>对话框内容</p>
  36 + <p>对话框内容</p>
  37 + <p>对话框内容</p>
  38 + </Modal>
31 39 </template>
32 40 <script>
33   - import { Tag } from 'iview';
  41 + import { Tag, Modal, iButton } from 'iview';
34 42 export default {
35   - components: { Tag }
  43 + components: { Tag, Modal, iButton },
  44 + data () {
  45 + return {
  46 + modal1: false
  47 + }
  48 + }
36 49 }
37 50 </script>
... ...