Blame view

src/components/cascader/cascader.vue 10.6 KB
0a48ac45   梁灏   Input add readonl...
1
  <template>
c463ab87   梁灏   add Cascader
2
      <div :class="classes" v-clickoutside="handleClose">
75e5c6a5   梁灏   Cascader support ...
3
4
5
          <div :class="[prefixCls + '-rel']" @click="toggleOpen">
              <slot>
                  <i-input
5a9a12cd   梁灏   update Cascader
6
                      :readonly="!filterable"
75e5c6a5   梁灏   Cascader support ...
7
                      :disabled="disabled"
7ec0b533   梁灏   Cascader support ...
8
9
                      :value="displayRender"
                      @on-change="handleInput"
75e5c6a5   梁灏   Cascader support ...
10
11
                      :size="size"
                      :placeholder="placeholder"></i-input>
47a7f21d   梁灏   support Cascader
12
                  <Icon type="ios-close" :class="[prefixCls + '-arrow']" v-show="showCloseIcon" @click.native.stop="clearSelect"></Icon>
75e5c6a5   梁灏   Cascader support ...
13
14
15
                  <Icon type="arrow-down-b" :class="[prefixCls + '-arrow']"></Icon>
              </slot>
          </div>
47a7f21d   梁灏   support Cascader
16
17
18
19
          <transition name="slide-up">
              <Drop v-show="visible">
                  <div>
                      <Caspanel
7ec0b533   梁灏   Cascader support ...
20
                          v-show="!filterable || (filterable && query === '')"
47a7f21d   梁灏   support Cascader
21
22
23
24
25
26
                          ref="caspanel"
                          :prefix-cls="prefixCls"
                          :data="data"
                          :disabled="disabled"
                          :change-on-select="changeOnSelect"
                          :trigger="trigger"></Caspanel>
7ec0b533   梁灏   Cascader support ...
27
28
29
30
31
32
33
34
35
36
                      <div :class="[prefixCls + '-dropdown']" v-show="filterable && query !== ''">
                          <ul :class="[selectPrefixCls + '-dropdown-list']">
                              <li
                                  :class="[selectPrefixCls + '-item', {
                                      [selectPrefixCls + '-item-disabled']: item.disabled
                                  }]"
                                  v-for="(item, index) in querySelections"
                                  @click="handleSelectItem(index)">{{ item.label }}</li>
                          </ul>
                      </div>
47a7f21d   梁灏   support Cascader
37
38
39
                  </div>
              </Drop>
          </transition>
6ff31952   梁灏   optimize Input sh...
40
      </div>
0a48ac45   梁灏   Input add readonl...
41
42
  </template>
  <script>
6ff31952   梁灏   optimize Input sh...
43
      import iInput from '../input/input.vue';
47a7f21d   梁灏   support Cascader
44
      import Drop from '../select/dropdown.vue';
c463ab87   梁灏   add Cascader
45
46
      import Icon from '../icon/icon.vue';
      import Caspanel from './caspanel.vue';
6ff31952   梁灏   optimize Input sh...
47
      import clickoutside from '../../directives/clickoutside';
c463ab87   梁灏   add Cascader
48
      import { oneOf } from '../../utils/assist';
47a7f21d   梁灏   support Cascader
49
      import Emitter from '../../mixins/emitter';
6ff31952   梁灏   optimize Input sh...
50
51
  
      const prefixCls = 'ivu-cascader';
7ec0b533   梁灏   Cascader support ...
52
      const selectPrefixCls = 'ivu-select';
6ff31952   梁灏   optimize Input sh...
53
  
0a48ac45   梁灏   Input add readonl...
54
      export default {
34ee7b4a   梁灏   support Tree & ad...
55
          name: 'Cascader',
47a7f21d   梁灏   support Cascader
56
57
          mixins: [ Emitter ],
          components: { iInput, Drop, Icon, Caspanel },
c463ab87   梁灏   add Cascader
58
          directives: { clickoutside },
0a48ac45   梁灏   Input add readonl...
59
          props: {
6ff31952   梁灏   optimize Input sh...
60
61
62
              data: {
                  type: Array,
                  default () {
b0893113   jingsam   :art: add eslint
63
                      return [];
6ff31952   梁灏   optimize Input sh...
64
65
66
                  }
              },
              value: {
9ec927b1   梁灏   update Cascader
67
68
                  type: Array,
                  default () {
b0893113   jingsam   :art: add eslint
69
                      return [];
9ec927b1   梁灏   update Cascader
70
                  }
6ff31952   梁灏   optimize Input sh...
71
72
73
74
75
76
77
              },
              disabled: {
                  type: Boolean,
                  default: false
              },
              clearable: {
                  type: Boolean,
c463ab87   梁灏   add Cascader
78
                  default: true
6ff31952   梁灏   optimize Input sh...
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
              },
              placeholder: {
                  type: String,
                  default: '请选择'
              },
              size: {
                  validator (value) {
                      return oneOf(value, ['small', 'large']);
                  }
              },
              trigger: {
                  validator (value) {
                      return oneOf(value, ['click', 'hover']);
                  },
                  default: 'click'
              },
              changeOnSelect: {
                  type: Boolean,
                  default: false
              },
              renderFormat: {
                  type: Function,
05b5dd7b   梁灏   update Cascader
101
                  default (label) {
bd4e3b9b   梁灏   update Cascader
102
                      return label.join(' / ');
6ff31952   梁灏   optimize Input sh...
103
                  }
f7ffdac5   梁灏   Cascader support ...
104
105
106
              },
              loadData: {
                  type: Function
5a9a12cd   梁灏   update Cascader
107
108
109
110
              },
              filterable: {
                  type: Boolean,
                  default: false
6ff31952   梁灏   optimize Input sh...
111
              }
0a48ac45   梁灏   Input add readonl...
112
113
114
          },
          data () {
              return {
6ff31952   梁灏   optimize Input sh...
115
                  prefixCls: prefixCls,
7ec0b533   梁灏   Cascader support ...
116
                  selectPrefixCls: selectPrefixCls,
c463ab87   梁灏   add Cascader
117
118
                  visible: false,
                  selected: [],
2810d8c7   梁灏   fixed #183
119
                  tmpSelected: [],
47a7f21d   梁灏   support Cascader
120
                  updatingValue: false,    // to fix set value in changeOnSelect type
7ec0b533   梁灏   Cascader support ...
121
122
                  currentValue: this.value,
                  query: ''
b0893113   jingsam   :art: add eslint
123
              };
0a48ac45   梁灏   Input add readonl...
124
125
          },
          computed: {
c463ab87   梁灏   add Cascader
126
127
128
129
              classes () {
                  return [
                      `${prefixCls}`,
                      {
165bb7c9   梁灏   update Cascader
130
                          [`${prefixCls}-show-clear`]: this.showCloseIcon,
05b5dd7b   梁灏   update Cascader
131
132
                          [`${prefixCls}-visible`]: this.visible,
                          [`${prefixCls}-disabled`]: this.disabled
c463ab87   梁灏   add Cascader
133
                      }
b0893113   jingsam   :art: add eslint
134
                  ];
c463ab87   梁灏   add Cascader
135
136
              },
              showCloseIcon () {
65b41a2d   梁灏   fixed #635
137
                  return this.currentValue && this.currentValue.length && this.clearable && !this.disabled;
c463ab87   梁灏   add Cascader
138
              },
6ff31952   梁灏   optimize Input sh...
139
140
141
142
143
144
              displayRender () {
                  let label = [];
                  for (let i = 0; i < this.selected.length; i++) {
                      label.push(this.selected[i].label);
                  }
  
165bb7c9   梁灏   update Cascader
145
                  return this.renderFormat(label, this.selected);
7ec0b533   梁灏   Cascader support ...
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
              },
              querySelections () {
                  let selections = [];
                  function getSelections (arr, label, value) {
                      for (let i = 0; i < arr.length; i++) {
                          let item = arr[i];
                          item.__label = label ? label + ' / ' + item.label : item.label;
                          item.__value = value ? value + ',' + item.value : item.value;
  
                          if (item.children && item.children.length) {
                              getSelections(item.children, item.__label, item.__value);
                              delete item.__label;
                              delete item.__value;
                          } else {
                              selections.push({
                                  label: item.__label,
                                  value: item.__value,
                                  item: item,
                                  disabled: !!item.disabled
                              });
                          }
                      }
                  }
                  getSelections(this.data);
                  selections = selections.filter(item => item.label.indexOf(this.query) > -1);
                  return selections;
6ff31952   梁灏   optimize Input sh...
172
              }
0a48ac45   梁灏   Input add readonl...
173
174
          },
          methods: {
c463ab87   梁灏   add Cascader
175
              clearSelect () {
65b41a2d   梁灏   fixed #635
176
                  if (this.disabled) return false;
47a7f21d   梁灏   support Cascader
177
178
                  const oldVal = JSON.stringify(this.currentValue);
                  this.currentValue = this.selected = this.tmpSelected = [];
165bb7c9   梁灏   update Cascader
179
                  this.handleClose();
47a7f21d   梁灏   support Cascader
180
181
182
                  this.emitValue(this.currentValue, oldVal);
  //                this.$broadcast('on-clear');
                  this.broadcast('Caspanel', 'on-clear');
c463ab87   梁灏   add Cascader
183
184
185
186
              },
              handleClose () {
                  this.visible = false;
              },
75e5c6a5   梁灏   Cascader support ...
187
              toggleOpen () {
2aa0aa6e   Rijn   fix bug: cascader...
188
                  if (this.disabled) return false;
75e5c6a5   梁灏   Cascader support ...
189
                  if (this.visible) {
7ec0b533   梁灏   Cascader support ...
190
                      if (!this.filterable) this.handleClose();
75e5c6a5   梁灏   Cascader support ...
191
192
193
194
                  } else {
                      this.onFocus();
                  }
              },
c463ab87   梁灏   add Cascader
195
196
              onFocus () {
                  this.visible = true;
47a7f21d   梁灏   support Cascader
197
198
                  if (!this.currentValue.length) {
                      this.broadcast('Caspanel', 'on-clear');
165bb7c9   梁灏   update Cascader
199
                  }
c463ab87   梁灏   add Cascader
200
201
              },
              updateResult (result) {
bd4e3b9b   梁灏   update Cascader
202
203
                  this.tmpSelected = result;
              },
165bb7c9   梁灏   update Cascader
204
205
              updateSelected (init = false) {
                  if (!this.changeOnSelect || init) {
47a7f21d   梁灏   support Cascader
206
207
208
                      this.broadcast('Caspanel', 'on-find-selected', {
                          value: this.currentValue
                      });
165bb7c9   梁灏   update Cascader
209
210
211
212
                  }
              },
              emitValue (val, oldVal) {
                  if (JSON.stringify(val) !== oldVal) {
47a7f21d   梁灏   support Cascader
213
                      this.$emit('on-change', this.currentValue, JSON.parse(JSON.stringify(this.selected)));
cc419499   梁灏   fixed #525
214
215
216
217
218
                      this.$nextTick(() => {
                          this.dispatch('FormItem', 'on-form-change', {
                              value: this.currentValue,
                              selected: JSON.parse(JSON.stringify(this.selected))
                          });
cd78c9c4   梁灏   some comps suppor...
219
                      });
165bb7c9   梁灏   update Cascader
220
                  }
7ec0b533   梁灏   Cascader support ...
221
222
223
224
225
226
227
228
229
230
231
232
233
              },
              handleInput (event) {
                  this.query = event.target.value;
              },
              handleSelectItem (index) {
                  const item = this.querySelections[index];
  
                  if (item.item.disabled) return false;
                  this.query = '';
                  const oldVal = JSON.stringify(this.currentValue);
                  this.currentValue = item.value.split(',');
                  this.emitValue(this.currentValue, oldVal);
                  this.handleClose();
c463ab87   梁灏   add Cascader
234
235
              }
          },
687c4562   梁灏   fixed #810
236
          created () {
47a7f21d   梁灏   support Cascader
237
238
239
240
241
242
243
              this.$on('on-result-change', (params) => {
                  // lastValue: is click the final val
                  // fromInit: is this emit from update value
                  const lastValue = params.lastValue;
                  const changeOnSelect = params.changeOnSelect;
                  const fromInit = params.fromInit;
  
bd4e3b9b   梁灏   update Cascader
244
                  if (lastValue || changeOnSelect) {
47a7f21d   梁灏   support Cascader
245
                      const oldVal = JSON.stringify(this.currentValue);
bd4e3b9b   梁灏   update Cascader
246
247
248
249
250
251
                      this.selected = this.tmpSelected;
  
                      let newVal = [];
                      this.selected.forEach((item) => {
                          newVal.push(item.value);
                      });
c463ab87   梁灏   add Cascader
252
  
165bb7c9   梁灏   update Cascader
253
                      if (!fromInit) {
2810d8c7   梁灏   fixed #183
254
                          this.updatingValue = true;
47a7f21d   梁灏   support Cascader
255
256
                          this.currentValue = newVal;
                          this.emitValue(this.currentValue, oldVal);
bd4e3b9b   梁灏   update Cascader
257
258
259
260
261
                      }
                  }
                  if (lastValue && !fromInit) {
                      this.handleClose();
                  }
47a7f21d   梁灏   support Cascader
262
              });
bd4e3b9b   梁灏   update Cascader
263
          },
687c4562   梁灏   fixed #810
264
265
266
          mounted () {
              this.updateSelected(true);
          },
bd4e3b9b   梁灏   update Cascader
267
268
269
          watch: {
              visible (val) {
                  if (val) {
47a7f21d   梁灏   support Cascader
270
                      if (this.currentValue.length) {
bd4e3b9b   梁灏   update Cascader
271
272
273
                          this.updateSelected();
                      }
                  }
bb1a3c38   梁灏   fixed #593
274
                  this.$emit('on-visible-change', val);
f46ebc38   梁灏   fixed #130
275
              },
47a7f21d   梁灏   support Cascader
276
277
              value (val) {
                  this.currentValue = val;
3bbb6b5f   梁灏   fixed #488
278
                  if (!val.length) this.selected = [];
47a7f21d   梁灏   support Cascader
279
280
281
              },
              currentValue () {
                  this.$emit('input', this.currentValue);
2810d8c7   梁灏   fixed #183
282
283
284
285
286
                  if (this.updatingValue) {
                      this.updatingValue = false;
                      return;
                  }
                  this.updateSelected(true);
48af1359   梁灏   fixed #553
287
              },
f7ffdac5   梁灏   Cascader support ...
288
289
290
291
292
              data: {
                  deep: true,
                  handler () {
                      this.$nextTick(() => this.updateSelected());
                  }
bd4e3b9b   梁灏   update Cascader
293
              }
0a48ac45   梁灏   Input add readonl...
294
          }
b0893113   jingsam   :art: add eslint
295
296
      };
  </script>