PageSourceSearch

https://www.neoobserver.com/subsiteSrc/cnPc/components/cascader/cascader/cascader.js

js neoobserver.com collected 2026-10-03 02:37:24 UTC 67,536 bytes, 2,095 lines download raw bytes

1;(function($){
2	/**
3	 * 阻止事件冒泡
4	 * @param event
5	 */
6	function stopPropagation(event) {
7	  event = event || window.event
8	  if (event.stopPropagation) {
9	    event.stopPropagation()
10	  } else {
11	    event.cancelBubble = true
12	  }
13	}
14	
15	/**
16	 * 级联各项节点对象
17	 * @param data        原始对象信息
18	 * @param cascader    级联对象
19	 * @param level       层级,从0开始
20	 * @param parentNode 父节点对象
21	 * @constructor
22	 */
23	function Node(data, cascader, level, parentNode) {
24	  this.data = data;
25	  this.cascader = cascader;
26	  this.config = cascader.config;
27	  this.props = cascader.props;
28	  this.level = level;
29	  this.parentNode = parentNode;
30	  // 引入的icon图标
31	  this.icons = cascader.icons;
32	  //该节点是否被选中 0:未选中,1:选中,2:不定
33	  this._checked = 0;
34	  // 是否正在加载中
35	  this._loading = false;
36	  // 每个Node的唯一标识
37	  this.nodeId = cascader.data.nodeId++;
38	}
39	
40	Node.prototype = {
41	  constructor: Node,
42	  /** 最顶级父节点 */
43	  get topParentNode() {
44	    return !this.parentNode && this || this.topParentNode;
45	  },
46	  /** 子节点 */
47	  childrenNode: undefined,
48	  get loading() {
49	    return this._loading;
50	  },
51	  set loading(loading) {
52	    var $li = this.$li;
53	    if ($li) {
54	      var rightIcon = this.icons.right;
55	      var loadingIcon = this.icons.loading;
56	      var $i = $li.find('i');
57	      if (loading) {
58	        $i.addClass(loadingIcon);
59	        $i.removeClass(rightIcon);
60	      } else {
61	        $i.addClass(rightIcon);
62	        $i.removeClass(loadingIcon);
63	      }
64	    }
65	    return this._loading = loading;
66	  },
67	  /** 当前节点的显示文本 */
68	  get label() {
69	    return this.data[this.props.label];
70	  },
71	  /** 当前节点的值 */
72	  get value() {
73	    return this.data[this.props.value];
74	  },
75	  /** 是否禁用 */
76	  get disabled() {
77	    var multiple = this.props.multiple;
78	    var maxSize = this.config.maxSize;
79	    var checkedNodeIds = this.cascader.data.checkedNodeIds;
80	    var disabledName = this.props.disabled;
81	    var checkStrictly = this.props.checkStrictly;
82	    // 检查是否超过最大值限制
83	    if (multiple && maxSize !== 0) {
84	      if (checkedNodeIds.length >= maxSize && checkedNodeIds.indexOf(this.nodeId) === -1) {
85	        // 如果是关联的多选,需要查询叶子节点是否有被选中的项
86	        if (!checkStrictly) {
87	          var leafChildren = this.getAllLeafChildren();
88	          var nodeIds = leafChildren.map(function (value) {
89	            return value.nodeId
90	          });
91	          // 如果叶子节点不包含,则直接返回true
92	          if (!nodeIds.some(function (nodeId) {
93	            return checkedNodeIds.indexOf(nodeId) !== -1;
94	          })) {
95	            return true;
96	          }
97	        } else {
98	          return true;
99	        }
100	      }
101	    }
102	    if (!checkStrictly) {
103	      var path = this.path;
104	      return path.some(function (node) {
105	        return node.data[disabledName];
106	      });
107	    } else {
108	      return this.data[disabledName];
109	    }
110	  },
111	  /** 子节点数据 */
112	  get children() {
113	    return this.data[this.props.children];
114	  },
115	  set children(children) {
116	    this.data[this.props.children] = children;
117	  },
118	  /** 叶子节点 */
119	  get leaf() {
120	    var leaf = this.data[this.props.leaf];
121	    if (typeof leaf === 'boolean') {
122	      return leaf;
123	    }
124	    // 如果children不为空,则判断是否是子节点
125	    if (this.children) {
126	      return this.children.length <= 0;
127	    }
128	    return true;
129	  },
130	  /** 当前单选值 */
131	  get activeNodeId() {
132	    return this.cascader.data.activeNodeId;
133	  },
134	  /** 当前复选框值 */
135	  get checkedNodeIds() {
136	    return this.cascader.data.checkedNodeIds;
137	  },
138	  /** 路径 */
139	  get path() {
140	    var parentNode = this.parentNode;
141	    if (parentNode) {
142	      return parentNode.path.concat([this]);
143	    } else {
144	      return [this];
145	    }
146	  },
147	  /** 是否正在搜索中 */
148	  get isFiltering() {
149	    return this.cascader.isFiltering;
150	  },
151	  /** 输入框的tag标签 */
152	  get $tag() {
153	    var cascader = this.cascader;
154	    var showAllLevels = this.config.showAllLevels;
155	    var disabled = this.config.disabled;
156	    var nodeDisabled = this.disabled;
157	    var disabledFixed = this.config.disabledFixed;
158	
159	    var label = this.getPathLabel(showAllLevels);
160	    var $tag = cascader.get$tag(label, !disabled && (!nodeDisabled || !disabledFixed));
161	    var self = this;
162	    $tag.find('i').click(function (event) {
163	      stopPropagation(event);
164	      self.selectedValue();
165	      cascader.removeTag(self.value, self);
166	    });
167	    return $tag;
168	  },
169	  /**
170	   * 完整路径的标签
171	   * @param showAllLevels
172	   * @returns {string}
173	   */
174	  getPathLabel: function (showAllLevels) {
175	    var path = this.path;
176	    var separator = this.config.separator;
177	
178	    var label;
179	    if (showAllLevels) {
180	      label = path.map(function (node) {
181	        return node.label;
182	      }).join(separator);
183	    } else {
184	      label = path[path.length - 1].label;
185	    }
186	    return label;
187	  },
188	  /**
189	   * 初始化
190	   */
191	  init: function () {
192	    var multiple = this.props.multiple;
193	    var checkStrictly = this.props.checkStrictly;
194	    var fromIcon = this.icons.from;
195	    var rightIcon = this.icons.right;
196	    var icon = '';
197	    var label = this.label;
198	    if (!this.leaf) {
199	      icon = rightIcon;
200	    }
201	    this.$li = $('<li role="menuitem" id="cascader-menu" tabindex="-1" class="el-cascader-node" aria-haspopup="true" aria-owns="c
201ascader-menu"><span class="el-cascader-node__label">' + label + '</span><i class="' + fromIcon + ' ' + icon + '"></i></li>');
202	
203	    // 节点渲染
204	    if (!multiple && !checkStrictly) {
205	      this._renderRadio();
206	    } else if (!multiple && checkStrictly) {
207	      this._renderRadioCheckStrictly();
208	    } else if (multiple && !checkStrictly) {
209	      this._renderMultiple();
210	    } else if (multiple && checkStrictly) {
211	      this._renderMultipleCheckStrictly();
212	    }
213	  },
214	  /**
215	   * 初始化可搜索li
216	   */
217	  initSuggestionLi: function () {
218	    var label = this.getPathLabel(true);
219	    this.$suggestionLi = $('<li tabindex="-1" class="el-cascader__suggestion-item"><span>' + label + '</span></li>');
220	    // 节点渲染
221	    this._renderFiltering();
222	  },
223	  /**
224	   * 绑定到菜单中
225	   * @param $list li节点
226	   */
227	  bind: function ($list) {
228	    this.init();
229	    $list.append(this.$li);
230	  },
231	  /**
232	   * 绑定可搜索到列表中
233	   * @param $list
234	   */
235	  bindSuggestion: function ($list) {
236	    this.initSuggestionLi();
237	    $list.append(this.$suggestionLi);
238	  },
239	  /**
240	   * 可搜索渲染
241	   * @private
242	   */
243	  _renderFiltering: function () {
244	    var $li = this.$suggestionLi;
245	    var nodeId = this.nodeId;
246	    var fromIcon = this.icons.from;
247	    var okIcon = this.icons.ok;
248	    var self = this;
249	    var cascader = this.cascader;
250	    var multiple = this.props.multiple;
251	
252	    var icon = '<i class="' + fromIcon + ' ' + okIcon + ' el-icon-check"></i>';
253	    $li.click(function (event) {
254	      stopPropagation(event);
255	      self.selectedValue();
256	      if (multiple) {
257	        if (self.checkedNodeIds.indexOf(nodeId) === -1) {
258	          $li.removeClass('is-checked');
259	          $li.find('.el-icon-check').remove();
260	        } else {
261	          $li.addClass('is-checked');
262	          $li.append(icon);
263	        }
264	      } else {
265	        // 关闭面板
266	        cascader.close();
267	      }
268	    });
269	
270	    if (multiple && self.checkedNodeIds.indexOf(nodeId) !== -1
271	      || !multiple && self.activeNodeId === nodeId) {
272	      $li.addClass('is-checked');
273	      $li.append(icon)
274	    }
275	  },
276	  /**
277	   * 单选&&关联
278	   * @private
279	   */
280	  _renderRadio: function () {
281	    var $li = this.$li;
282	    var nodeId = this.nodeId;
283	    var fromIcon = this.icons.from;
284	    var okIcon = this.icons.ok;
285	    var level = this.level;
286	    var leaf = this.leaf;
287	    var self = this;
288	    var cascader = this.cascader;
289	    var activeNode = this.cascader.data.activeNode;
290	    var parentNode = this.parentNode;
291	
292	    if (self.activeNodeId && activeNode.path.some(function (node) {
293	      return node.nodeId === nodeId;
294	    })) {
295	      if (self.activeNodeId === nodeId) {
296	        $li.prepend('<i class="' + fromIcon + ' ' + okIcon + ' el-cascader-node__prefix"></i>');
297	      }
298	      $li.addClass('is-active');
299	      $li.addClass('in-checked-path');
300	    }
301	
302	    // 是否禁用
303	    if (this.disabled) {
304	      $li.addClass('is-disabled');
305	      return;
306	    }
307	
308	    $li.addClass('is-selectable');
309	
310	    if (parentNode) {
311	      parentNode.$li.siblings().removeClass('in-active-path');
312	      parentNode.$li.addClass('in-active-path');
313	    }
314	
315	    // 触发下一个节点
316	    this._liClick(function (event) {
317	      stopPropagation(event);
318	      var childrenNode = self.childrenNode;
319	      if (leaf && event.type === 'click') {
320	        self.selectedValue();
321	        // 关闭面板
322	        cascader.close();
323	      }
324	      // 添加下级菜单
325	      cascader._appendMenu(childrenNode, level + 1, self);
326	    });
327	  },
328	  /**
329	   * 单选&&非关联
330	   * @private
331	   */
332	  _renderRadioCheckStrictly: function () {
333	    var $li = this.$li;
334	    var nodeId = this.nodeId;
335	    var level = this.level;
336	    var leaf = this.leaf;
337	    var self = this;
338	    var cascader = this.cascader;
339	    var activeNode = cascader.data.activeNode;
340	    var parentNode = this.parentNode;
341	
342	    $li.addClass('is-selectable');
343	    // 任意一级单选
344	    var $radio = $('<label role="radio" tabindex="0" class="el-radio"><span class="el-radio__input"><span class="el-radio__inner"></span><input type="radio" aria-hidden="true" tabindex="-1" class="el-radio__original" value="' + nodeId + '"></span><span class="el-radio__label"><span></span></span></label>');
345	    this.$radio = $radio;
346	    $li.prepend($radio);
347	    if (parentNode) {
348	      parentNode.$li.siblings().removeClass('in-active-path');
349	      parentNode.$li.addClass('in-active-path');
350	    }
351	
352	    // 触发下一个节点
353	    this._liClick(function (event) {
354	      stopPropagation(event);
355	      var childrenNode = self.childrenNode;
356	      if (!self.disabled && leaf && event.type === 'click') {
357	        self.selectedValue();
358	      }
359	      // 添加下级菜单
360	      cascader._appendMenu(childrenNode, level + 1, self);
361	    });
362	
363	    if (self.activeNodeId && activeNode.path.some(function (node) {
364	      return node.nodeId === nodeId;
365	    })) {
366	      if (self.activeNodeId === nodeId) {
367	        $radio.find('.el-radio__input').addClass('is-checked');
368	      }
369	      $li.addClass('is-active');
370	      $li.addClass('in-checked-path');
371	    }
372	
373	    if (this.disabled) {
374	      $radio.addClass('is-disabled');
375	      $radio.find('.el-radio__input').addClass('is-disabled');
376	      return;
377	    }
378	    // 选中事件
379	    $radio.click(function (event) {
380	      event.preventDefault();
381	      !leaf && self.selectedValue();
382	    });
383	  },
384	  /**
385	   * 多选&&关联
386	   * @private
387	   */
388	  _renderMultiple: function () {
389	    var $li = this.$li;
390	    var level = this.level;
391	    var leaf = this.leaf;
392	    var self = this;
393	    var cascader = this.cascader;
394	    var checked = this._checked;
395	    var parentNode = this.parentNode;
396	
397	    $li.addClass('el-cascader-node');
398	
399	    // 多选框
400	    var $checked = $('<label class="el-checkbox"><span class="el-checkbox__input"><span class="el-checkbox__inner"></span><input type="checkbox" aria-hidden="false" class="el-checkbox__original" value=""></span></label>');
401	    this.$checked = $checked;
402	    $li.prepend($checked);
403	
404	    // 渲染
405	    if (checked === 1) {
406	      this.$checked.find('.el-checkbox__input').addClass('is-checked');
407	    } else if (checked === 2) {
408	      this.$checked.find('.el-checkbox__input').addClass('is-indeterminate');
409	    }
410	
411	    if (parentNode) {
412	      parentNode.$li.siblings().removeClass('in-active-path');
413	      parentNode.$li.addClass('in-active-path');
414	    }
415	
416	    // 触发下一个节点
417	    this._liClick(function (event) {
418	      stopPropagation(event);
419	      var childrenNode = self.childrenNode;
420	      if (!self.disabled && leaf && event.type === 'click') {
421	        // 最后一级就默认选择
422	        self.selectedValue();
423	      }
424	      // 添加下级菜单
425	      cascader._appendMenu(childrenNode, level + 1, self);
426	    });
427	
428	    if (this.disabled) {
429	      $li.addClass('is-disabled');
430	      $checked.addClass('is-disabled');
431	      $checked.find('.el-checkbox__input').addClass('is-disabled');
432	      return;
433	    }
434	
435	    // 选中事件
436	    $checked.click(function (event) {
437	      event.preventDefault();
438	      if (!leaf) {
439	        var childrenNode = self.childrenNode;
440	        self.selectedValue();
441	        cascader._appendMenu(childrenNode, level + 1, self);
442	      }
443	    });
444	  },
445	  /**
446	   * 多选&&非关联
447	   * @private
448	   */
449	  _renderMultipleCheckStrictly: function () {
450	    var $li = this.$li;
451	    var level = this.level;
452	    var leaf = this.leaf;
453	    var self = this;
454	    var cascader = this.cascader;
455	    var checkedNodeIds = cascader.data.checkedNodeIds;
456	    var checkedNodes = cascader.data.checkedNodes;
457	    var nodeId = this.nodeId;
458	    var parentNode = this.parentNode;
459	
460	    $li.addClass('el-cascader-node is-selectable');
461	
462	    // 多选框
463	    var $checked = $('<label class="el-checkbox"><span class="el-checkbox__input"><span class="el-checkbox__inner"></span><input type="checkbox" aria-hidden="false" class="el-checkbox__original" value=""></span></label>');
464	    this.$checked = $checked;
465	    $li.prepend($checked);
466	
467	    // 渲染
468	    var exist = checkedNodes.some(function (node) {
469	      return node.path.some(function (node) {
470	        return node.nodeId === nodeId;
471	      })
472	    });
473	    if (exist) {
474	      $li.addClass('in-checked-path');
475	      if (checkedNodeIds.indexOf(nodeId) !== -1) {
476	        this.$checked.find('.el-checkbox__input').addClass('is-checked');
477	      }
478	    }
479	
480	    if (parentNode) {
481	      parentNode.$li.siblings().removeClass('in-active-path');
482	      parentNode.$li.addClass('in-active-path');
483	    }
484	
485	    // 触发下一个节点
486	    this._liClick(function (event) {
487	      stopPropagation(event);
488	      var childrenNode = self.childrenNode;
489	      if (!self.disabled && leaf && event.type === 'click') {
490	        // 最后一级就默认选择
491	        self.selectedValue();
492	      }
493	      // 添加下级菜单
494	      cascader._appendMenu(childrenNode, level + 1, self);
495	    });
496	
497	    if (this.disabled) {
498	      $checked.addClass('is-disabled');
499	      $checked.find('.el-checkbox__input').addClass('is-disabled');
500	      return;
501	    }
502	    // 选中事件
503	    $checked.click(function (event) {
504	      event.preventDefault();
505	      if (!leaf) {
506	        self.selectedValue();
507	        var childrenNode = self.childrenNode;
508	        // 添加下级菜单
509	        cascader._appendMenu(childrenNode, level + 1, self);
510	      }
511	    });
512	  },
513	  /**
514	   * 向上传递
515	   * @param callback 执行方法,如果返回false,则中断执行
516	   * @param advance 是否先执行一次
517	   * @param self  自身
518	   */
519	  transferParent: function (callback, advance, self) {
520	    if (!self) {
521	      self = this;
522	    }
523	    if (this !== self || advance) {
524	      var goOn = callback && callback(this);
525	      if (goOn === false) {
526	        return;
527	      }
528	    }
529	    this.parentNode && this.parentNode.transferParent(callback, advance, self);
530	  },
531	  /**
532	   * 向下传递
533	   * @param callback 执行的方法,如果返回false,则中断执行
534	   * @param advance 是否先执行一次
535	   * @param self  自身
536	   */
537	  transferChildren: function (callback, advance, self) {
538	    if (!self) {
539	      self = this;
540	    }
541	    if (this !== self || advance) {
542	      var goOn = callback && callback(this);
543	      if (goOn === false) {
544	        return;
545	      }
546	    }
547	    var children = this.getChildren();
548	    if (children && children.length > 0) {
549	      for (var index in children) {
550	        children[index].transferChildren(callback, advance, self);
551	      }
552	    }
553	  },
554	  /**
555	   * 设置级联值
556	   */
557	  selectedValue: function () {
558	    var nodeId = this.nodeId;
559	    var cascader = this.cascader;
560	    var multiple = this.props.multiple;
561	    var checkStrictly = this.props.checkStrictly;
562	    var leaf = this.leaf;
563	    if (!multiple && (leaf || checkStrictly)) {
564	      cascader._setActiveValue(nodeId, this);
565	    } else if (multiple) {
566	      var checkedNodeIds = cascader.data.checkedNodeIds;
567	      var checkedNodes = cascader.data.checkedNodes;
568	      var disabledFixed = this.config.disabledFixed;
569	      var paths;
570	      if (checkStrictly) {
571	        var index = checkedNodeIds.indexOf(nodeId);
572	        if (index === -1) {
573	          paths = checkedNodes.concat([this]);
574	        } else {
575	          paths = checkedNodes.concat();
576	          paths.splice(index, 1);
577	        }
578	      } else {
579	        var allLeafChildren = this.getAllLeafChildren();
580	        var checked;
581	        if (this._checked !== 1 && disabledFixed) {
582	          checked = this._getMultipleChecked(allLeafChildren);
583	        } else {
584	          checked = this._checked;
585	        }
586	        if (checked === 1) {
587	          // 选中->未选中
588	          paths = checkedNodes.filter(function (node1) {
589	            return !allLeafChildren.some(function (node2) {
590	              return node1.nodeId === node2.nodeId;
591	            });
592	          });
593	        } else {
594	          // 未选中、部分选中->选中
595	          var add = allLeafChildren.filter(function (node) {
596	            return checkedNodeIds.indexOf(node.nodeId) === -1;
597	          });
598	          paths = checkedNodes.concat(add);
599	        }
600	      }
601	      var nodeIds = paths.map(function (node) {
602	        return node.nodeId;
603	      });
604	      cascader._setCheckedValue(nodeIds, paths);
605	    }
606	  },
607	  _liLoad: function (event, callback) {
608	    var leaf = this.leaf;
609	    var lazy = this.props.lazy;
610	    var lazyLoad = this.props.lazyLoad;
611	    var children = this.children;
612	    var self = this;
613	    var cascader = this.cascader;
614	    var level = this.level;
615	    var multiple = this.props.multiple;
616	    var checkStrictly = this.props.checkStrictly;
617	    if (!leaf && (!children || children.length === 0) && lazy) {
618	      if (!self.loading) {
619	        self.loading = true;
620	        lazyLoad(self, function (nodes) {
621	          self.loading = false;
622	          self.setChildren(cascader.initNodes(nodes, level + 1, self));
623	          self.children = nodes;
624	          callback && callback(event);
625	          // 多选&关联时,重新同步下父级节点的样式
626	          multiple && !checkStrictly && self.transferParent(function (node) {
627	            node.syncStyle();
628	          }, true);
629	        });
630	      }
631	    } else {
632	      callback && callback(event);
633	    }
634	  },
635	  /**
636	   * 点击li事件
637	   * @param callback
638	   * @private
639	   */
640	  _liClick: function (callback) {
641	    var leaf = this.leaf;
642	    var $li = this.$li;
643	    var self = this;
644	
645	    function load(event) {
646	      self._liLoad(event, callback);
647	    }
648	
649	    if (this.props.expandTrigger === "click" || leaf) {
650	      $li.click(load);
651	    }
652	    if (this.props.expandTrigger === "hover") {
653	      $li.mouseenter(load);
654	    }
655	  },
656	  setChildren: function (children) {
657	    this.childrenNode = children;
658	  },
659	  getChildren: function () {
660	    return this.childrenNode;
661	  },
662	  /**
663	   * 同步样式
664	   */
665	  syncStyle: function () {
666	    var multiple = this.props.multiple;
667	    var checkStrictly = this.props.checkStrictly;
668	    if (multiple) {
669	      //多选
670	      if (checkStrictly) {
671	        this._sync.syncMultipleCheckStrictly(this);
672	      } else {
673	        this._sync.syncMultiple(this);
674	      }
675	    } else {
676	      //单选
677	      if (checkStrictly) {
678	        this._sync.syncRadioCheckStrictly(this);
679	      } else {
680	        this._sync.syncRadio(this);
681	      }
682	    }
683	  },
684	  /**
685	   * 同步本节点样式
686	   */
687	  _sync: {
688	    /**
689	     * 同步单选关联样式
690	     */
691	    syncRadio: function (self) {
692	      var $li = self.$li;
693	      var fromIcon = self.icons.from;
694	      var okIcon = self.icons.ok;
695	      var multiple = self.props.multiple;
696	      var checkStrictly = self.props.checkStrictly;
697	      var nodeId = self.nodeId;
698	      if (!$li || multiple || checkStrictly) {
699	        return;
700	      }
701	      var activeNode = self.cascader.data.activeNode;
702	      if (self.activeNodeId === nodeId) {
703	        var ok = $li.find('.' + okIcon);
704	        if (ok.length === 0) {
705	          $li.prepend('<i class="' + fromIcon + ' ' + okIcon + ' el-cascader-node__prefix"></i>');
706	        }
707	      } else {
708	        $li.find('.' + okIcon).remove();
709	      }
710	      if (activeNode && activeNode.path.some(function (node) {
711	        return node.nodeId === nodeId;
712	      })) {
713	        $li.addClass('is-active');
714	        $li.addClass('in-checked-path');
715	      } else {
716	        $li.removeClass('is-active');
717	        $li.removeClass('in-checked-path');
718	      }
719	    },
720	    /**
721	     * 同步单选非关联样式
722	     */
723	    syncRadioCheckStrictly: function (self) {
724	      var $li = self.$li;
725	      var checkStrictly = self.props.checkStrictly;
726	      var multiple = self.props.multiple;
727	      if (!$li || multiple || !checkStrictly) {
728	        return;
729	      }
730	      var $radio = self.$radio;
731	      var activeNode = self.cascader.data.activeNode;
732	      var nodeId = self.nodeId;
733	      if (self.activeNodeId === nodeId) {
734	        $radio.find('.el-radio__input').addClass('is-checked');
735	      } else {
736	        $radio.find('.el-radio__input').removeClass('is-checked');
737	      }
738	      if (activeNode && activeNode.path.some(function (node) {
739	        return node.nodeId === nodeId;
740	      })) {
741	        $li.addClass('is-active');
742	        $li.addClass('in-checked-path');
743	      } else {
744	        $li.removeClass('is-active');
745	        $li.removeClass('in-checked-path');
746	      }
747	    },
748	    /**
749	     * 同步多选关联样式
750	     */
751	    syncMultiple: function (self) {
752	      var $li = self.$li;
753	      var checkStrictly = self.props.checkStrictly;
754	      var multiple = self.props.multiple;
755	      var disabledFixed = self.config.disabledFixed;
756	      if (!multiple || checkStrictly) {
757	        return;
758	      }
759	      var allLeafChildren = self.getAllLeafChildren(disabledFixed);
760	      // 全部未选中 0
761	      // 全部选中 1
762	      // 部分选中 2
763	      var checked = self._getMultipleChecked(allLeafChildren);
764	      self._checked = checked;
765	      if (!$li) {
766	        return;
767	      }
768	      var $checkbox = self.$checked.find('.el-checkbox__input');
769	      if (checked === 0) {
770	        $checkbox.removeClass('is-checked');
771	        $checkbox.removeClass('is-indeterminate');
772	      } else if (checked === 1) {
773	        $checkbox.removeClass('is-indeterminate');
774	        $checkbox.addClass('is-checked');
775	      } else if (checked === 2) {
776	        $checkbox.removeClass('is-checked');
777	        $checkbox.addClass('is-indeterminate');
778	      }
779	    },
780	    /**
781	     * 同步多选非关联样式
782	     */
783	    syncMultipleCheckStrictly: function (self) {
784	      var $li = self.$li;
785	      var checkStrictly = self.props.checkStrictly;
786	      var multiple = self.props.multiple;
787	      if (!$li || !multiple || !checkStrictly) {
788	        return;
789	      }
790	      var checkedNodes = self.cascader.data.checkedNodes;
791	      var checkedNodeIds = self.checkedNodeIds;
792	      var nodeId = self.nodeId;
793	      var exist = checkedNodes.some(function (node) {
794	        return node.path.some(function (node) {
795	          return node.nodeId === nodeId;
796	        });
797	      });
798	      var $checkbox = self.$checked.find('.el-checkbox__input');
799	      if (checkedNodeIds.some(function (checkedNodeId) {
800	        return checkedNodeId === nodeId;
801	      })) {
802	        // 选中
803	        $checkbox.addClass('is-checked');
804	      } else {
805	        // 未选中
806	        $checkbox.removeClass('is-checked');
807	      }
808	      if (exist) {
809	        $li.addClass('in-checked-path');
810	      } else {
811	        $li.removeClass('in-checked-path');
812	      }
813	    }
814	  },
815	  /**
816	   * 获取叶子节点value值
817	   * @param disabled 是否包含禁用,默认不包含
818	   * @returns {Node[]|*[]}
819	   */
820	  getAllLeafChildren: function (disabled) {
821	    var leaf = this.leaf;
822	    if (leaf) {
823	      return [this];
824	    } else {
825	      var leafs = [];
826	      this.transferChildren(function (node) {
827	        if (node.disabled && !disabled) {
828	          return false;
829	        }
830	        node.leaf && leafs.push(node);
831	      });
832	      return leafs;
833	    }
834	  },
835	  /**
836	   * 展开当前节点
837	   */
838	  expandPanel: function () {
839	    var path = this.path;
840	    var cascader = this.cascader;
841	    path.forEach(function (node, index, array) {
842	      if (index !== array.length - 1) {
843	        var childrenNode = node.childrenNode;
844	        cascader._appendMenu(childrenNode, node.level + 1, node.parentNode);
845	      }
846	    });
847	  },
848	  _getMultipleChecked: function (leafNodes) {
849	    var cascader = this.cascader;
850	    var checkedNodeIds = cascader.data.checkedNodeIds;
851	    var allLeafIds = leafNodes.map(function (node) {
852	      return node.nodeId;
853	    });
854	    // 全部未选中 0
855	    // 全部选中 1
856	    // 部分选中 2
857	    var checked = 0;
858	    for (var i = 0; i < allLeafIds.length; i++) {
859	      var child = allLeafIds[i];
860	      if (checked === 2) {
861	        break;
862	      }
863	      if (checkedNodeIds.indexOf(child) !== -1) {
864	        if (i > 0 && checked !== 1) {
865	          checked = 2;
866	        } else {
867	          checked = 1;
868	        }
869	      } else {
870	        // 当全部选中时,则改为部分选中,否则全部未选中
871	        checked = checked === 1 ? 2 : 0;
872	      }
873	    }
874	    return checked;
875	  }
876	};
877	
878	function Cascader(config) {
879	  this.config = $.extend(true, {
880	    elem: '',             //绑定元素
881	    value: null,          //预设值
882	    options: [],          //可选项数据源,键名可通过 Props 属性配置
883	    empty: '暂无数据',	  //无匹配选项时的内容
884	    placeholder: '请选择',//输入框占位文本
885	    disabled: false,      //是否禁用
886	    clearable: false,     //是否支持清空选项
887	    showAllLevels: true,  //输入框中是否显示选中值的完整路径
888	    collapseTags: false,  //多选模式下是否折叠Tag
889	    minCollapseTagsNumber: 1, //最小折叠标签数
890	    separator: ' / ',     //选项分隔符
891	    filterable: false,    //是否可搜索选项
892	    filterMethod: function (node, keyword) {
893	      return node.path.some(function (node) {
894	        return node.label.indexOf(keyword) !== -1;
895	      });
896	    }, //自定义搜索逻辑,第一个参数是节点node,第二个参数是搜索关键词keyword,通过返回布尔值表示是否命中
897	    debounce: 300,        //搜索关键词输入的去抖延迟,毫秒
898	    beforeFilter: function (value) {
899	      return true;
900	    },//筛选之前的钩子,参数为输入的值,若返回 false,则停止筛选
901	    popperClass: '',        //	自定义浮层类名	string
902	    extendClass: false,     //继承class样式
903	    extendStyle: false,     //继承style样式
904	    disabledFixed: false,   //固定禁用项,使禁用项不被清理删除,禁用项只能通过函数添加或初始值添加,默认禁用项不可被函数或初始值添加
905	    maxSize: 0,           // 多选选中的最大数量,0表示不限制
906	    props: {
907	      strictMode: false,      //严格模式,设置value严格按照层级结构.例如:[[1,2,3],[1,2,4]]
908	      expandTrigger: 'click', //次级菜单的展开方式	string	click / hover	'click'
909	      multiple: false,	      //是否多选	boolean	-	false
910	      checkStrictly: false, 	//是否严格的遵守父子节点不互相关联	boolean	-	false
911	      lazy: false,	        //是否动态加载子节点,需与 lazyLoad 方法结合使用	boolean	-	false
912	      lazyLoad: function (node, resolve) {
913	      },	//加载动态数据的方法,仅在 lazy 为 true 时有效	function(node, resolve),node为当前点击的节点,resolve为数据加载完成的回调(必须调用)
914	      value: 'value',	        //指定选项的值为选项对象的某个属性值	string	—	'value'
915	      label: 'label',	        //指定选项标签为选项对象的某个属性值	string	—	'label'
916	      children: 'children',	  //指定选项的子选项为选项对象的某个属性值	string	—	'children'
917	      disabled: 'disabled',   //指定选项的禁用为选项对象的某个属性值	string	—	'disabled'
918	      leaf: 'leaf'	          //指定选项的叶子节点的标志位为选项对象的某个属性值	string	—	'leaf'
919	    }
920	  }, config);
921	  this.data = {
922	    nodeId: 1,            //nodeId的自增值
923	    nodes: [],            //存储Node对象
924	    menuData: [],         //压入菜单的数据
925	    activeNodeId: null,   //存放NodeId
926	    activeNode: null,     //存放Node
927	    checkedNodeIds: [],   //存放多个NodeId
928	    checkedNodes: []  //存放多个Node
929	  };
930	  // 面板是否展开
931	  this.showPanel = false;
932	  this.event = {
933	    // 值变更事件
934	    change: [],
935	    // 打开事件
936	    open: [],
937	    // 关闭事件
938	    close: []
939	  }
940	  // 是否正在搜索中
941	  this.filtering = false;
942	  // 初始化
943	  this._init();
944	  // 面板关闭事件id
945	  this.closeEventId = 0;
946	  // 是否进入maxSize模式
947	  this._maxSizeMode = null;
948	}
949	
950	Cascader.prototype = {
951	  constructor: Cascader,
952	  get props() {
953	    return this.config.props;
954	  },
955	  get isFiltering() {
956	    return this.filtering;
957	  },
958	  set isFiltering(filtering) {
959	    if (this.filtering === filtering) {
960	      return;
961	    }
962	    this.filtering = !!filtering;
963	    var $panel = this.$panel;
964	    if (this.filtering) {
965	      $panel.find('.el-cascader-panel').hide();
966	      $panel.find('.el-cascader__suggestion-panel').show();
967	    } else {
968	      $panel.find('.el-cascader-panel').show();
969	      $panel.find('.el-cascader__suggestion-panel').hide();
970	      this.$tagsInput && this.$tagsInput.val('')
971	    }
972	  },
973	  set maxSizeMode(maxSizeMode) {
974	    if (this._maxSizeMode !== maxSizeMode) {
975	      this._maxSizeMode = maxSizeMode;
976	      this.refreshMenu();
977	    }
978	  },
979	  icons: {
980	    from: 'aykjFont',
981	    down: 'aykjxialajiantouxiao',
982	    close: 'aykjxiaoguanbi',
983	    right: 'aykjyoujiantou1',
984	    ok: 'aykjduigou3',
985	    loading: 'layui-icon-loading-1 layui-anim layui-anim-rotate layui-anim-loop'
986	  },
987	  // 初始化
988	  _init: function () {
989	    this._checkConfig();
990	    // 初始化输入框
991	    this._initInput();
992	    // 初始化面板
993	    this._initPanel();
994	    // 初始化选项值
995	    this.setOptions(this.config.options);
996	    var self = this;
997	    // 监听滚动条
998	    $(window).scroll(function () {
999	      self._resetXY();
1000	    });
1001	    // 监听窗口
1002	    $(window).resize(function () {
1003	      self._resetXY();
1004	    });
1005	    // 点击事件,展开面板
1006	    this.$div.click(function (event) {
1007	      if (self.config.disabled) {
1008	        return;
1009	      }
1010	      var show = self.showPanel;
1011	      if (!show) {
1012	        self.open();
1013	      } else {
1014	        self.close();
1015	      }
1016	    });
1017	  },
1018	  /**
1019	   * 检查配置
1020	   * @private
1021	   */
1022	  _checkConfig: function () {
1023	    var elem = this.config.elem;
1024	    if (!elem || $(elem).length === 0) {
1025	      throw new Error("缺少elem节点选择器");
1026	    }
1027	    var maxSize = this.config.maxSize;
1028	    if (typeof maxSize !== 'number' || maxSize < 0) {
1029	      throw new Error("maxSize应是一个大于等于0的有效的number值");
1030	    }
1031	    if (!Array.isArray(this.config.options)) {
1032	      throw new Error("options不是一个有效的数组");
1033	    }
1034	  },
1035	  /**
1036	   * 初始化根目录
1037	   * @private
1038	   */
1039	  _initRoot: function () {
1040	    var lazy = this.props.lazy;
1041	    var lazyLoad = this.props.lazyLoad;
1042	    var self = this;
1043	    var nodes = this.data.nodes;
1044	    if (nodes.length > 0 || !lazy) {
1045	      this._appendMenu(nodes, 0);
1046	    } else if (lazy) {
1047	      this._appendMenu(nodes, 0);
1048	      lazyLoad({
1049	        root: true,
1050	        level: 0
1051	      }, function (nodes) {
1052	        self.data.nodes = self.initNodes(nodes, 0, null);
1053	        self._appendMenu(self.data.nodes, 0);
1054	      });
1055	    }
1056	  },
1057	  /**
1058	   * 设置选项值
1059	   * @param options
1060	   */
1061	  setOptions: function (options) {
1062	    this.config.options = options;
1063	    // 初始化节点
1064	    this.data.nodes = this.initNodes(options, 0, null);
1065	    // 初始化根目录
1066	    this._initRoot();
1067	    // 初始化值
1068	    this.setValue(this.config.value);
1069	  },
1070	  // 面板定位
1071	  _resetXY: function () {
1072	    var $div = this.$div;
1073	    var offset = $div.offset();
1074	    var $panel = this.$panel;
1075	    if ($panel) {
1076	      var windowHeight = window.innerHeight;
1077	      var windowWidth = window.innerWidth;
1078	      var panelHeight = $panel.height();
1079	      var panelWidth = $panel.width();
1080	      var divHeight = $div.height();
1081	      var boundingClientRect = $div[0].getBoundingClientRect();
1082	      var $arrow = $panel.find('.popper__arrow');
1083	
1084	      // 距离右边界的偏差值
1085	      var offsetDiff = Math.min(windowWidth - boundingClientRect.x - panelWidth - 5, 0);
1086	
1087	      var bottomHeight = windowHeight - (boundingClientRect.top + divHeight);
1088	      if (bottomHeight < panelHeight && boundingClientRect.top > panelHeight + 20) {
1089	        $panel.attr('x-placement', 'top-start')
1090	        // 向上
1091	        $panel.css({
1092	          top: offset.top - 20 - panelHeight + 'px',
1093	          left: offset.left + offsetDiff + 'px'
1094	        });
1095	      } else {
1096	        $panel.attr('x-placement', 'bottom-start');
1097	        // 距离底部边界的偏差值
1098	        var yOffset = Math.max(panelHeight - (windowHeight - boundingClientRect.y - divHeight - 15), 0);
1099	        // 向下
1100	        $panel.css({
1101	          top: offset.top + divHeight - yOffset + 'px',
1102	          left: offset.left + offsetDiff + 'px'
1103	        });
1104	      }
1105	      // 箭头偏移
1106	      $arrow.css("left", 35 - offsetDiff + "px");
1107	    }
1108	  },
1109	  get $menus() {
1110	    return this.$panel && this.$panel.find('.el-cascader-panel .el-cascader-menu');
1111	  },
1112	  // 初始化输入框
1113	  _initInput: function () {
1114	    var $e = $(this.config.elem);
1115	    var self = this;
1116	    // 当绑定的元素带有value属性,并且对象未设置值时,设置一个初始值
1117	    if (this.config.value === null && $e.attr('value')) {
1118	      this.config.value = $e.attr('value');
1119	    }
1120	    var placeholder = this.config.placeholder;
1121	    var fromIcon = this.icons.from;
1122	    var downIcon = this.icons.down;
1123	    var multiple = this.props.multiple;
1124	    var extendClass = this.config.extendClass;
1125	    var extendStyle = this.config.extendStyle;
1126	
1127	    this.$div = $('<div class="el-cascader"></div>');
1128	    if (extendStyle) {
1129	      var style = $e.attr('style');
1130	      if (style) {
1131	        this.$div.attr('style', style);
1132	      }
1133	    }
1134	    if (extendClass) {
1135	      var className = $e.attr('class');
1136	      if (className) {
1137	        className.split(' ').forEach(function (name) {
1138	          self.$div.addClass(name);
1139	        });
1140	      }
1141	    }
1142	    this.$input = $('<div class="el-input el-input--suffix">' +
1143	      '<input type="text" readonly="readonly" autocomplete="off" placeholder="' + placeholder + '" class="el-input__inner">' +
1144	      '<span class="el-input__suffix">' +
1145	      '<span class="el-input__suffix-inner">' +
1146	      '<i class="el-icon-arrow-down ' + fromIcon + ' ' + downIcon + '" style="font-size: 12px"></i>' +
1147	      '</span></span>' +
1148	      '</div>')
1149	    this.$div.append(this.$input);
1150	    this.$inputRow = this.$input.find('.el-input__inner');
1151	    // 多选标签
1152	    if (multiple) {
1153	      this.$tags = $('<div class="el-cascader__tags"><!----></div>');
1154	      this.$div.append(this.$tags);
1155	    }
1156	    var element = this._initHideElement($e);
1157	    // 在后面插入元素
1158	    element.after(this.$div);
1159	    this.$icon = this.$input.find('i');
1160	    this._initFilterableInputEvent();
1161	    this.disabled(this.config.disabled);
1162	  },
1163	  /**
1164	   * 初始化隐藏元素input,主要用于layui的表单验证
1165	   * @param $e
1166	   * @private
1167	   */
1168	  _initHideElement: function ($e) {
1169	    var tagName = $e.prop("tagName").toLowerCase();
1170	    // 保存原始元素
1171	    if (tagName === 'input') {
1172	      $e.hide();
1173	      // $e.attr('type', 'hidden')
1174				$e[0].type = 'hidden'
1175	      this.$ec = $e;
1176	      return $e;
1177	    } else {
1178	      var attributes = $e[0].attributes;
1179	      var $input = $('<input />');
1180	      var keys = Object.keys(attributes);
1181	      for (var key in keys) {
1182	        var attribute = attributes[key];
1183	        $input.attr(attribute.name, attribute.value);
1184	      }
1185	      $input.hide();
1186	      // $input.attr('type', 'hidden')
1187				$input[0].type = 'hidden'
1188	      this.$ec = $input;
1189	      $e.before($input);
1190	      $e.remove();
1191	      return $input;
1192	    }
1193	  },
1194	  /**
1195	   * 初始化可搜索监听事件
1196	   * @private
1197	   */
1198	  _initFilterableInputEvent: function () {
1199	    var filterable = this.config.filterable;
1200	    if (!filterable) {
1201	      return;
1202	    }
1203	    var timeoutID;
1204	    var multiple = this.props.multiple;
1205	    var debounce = this.config.debounce;
1206	    var placeholder = this.config.placeholder;
1207	    var beforeFilter = this.config.beforeFilter;
1208	    var filterMethod = this.config.filterMethod;
1209	    var checkStrictly = this.props.checkStrictly;
1210	    var self = this;
1211	
1212	    function filter(event) {
1213	      var input = this;
1214	      if (timeoutID) {
1215	        clearTimeout(timeoutID);
1216	      }
1217	      timeoutID = setTimeout(function () {
1218	        timeoutID = null;
1219	        var val = $(input).val();
1220	        if (!val) {
1221	          self.isFiltering = false;
1222	          return;
1223	        }
1224	        self.open();
1225	        if (typeof beforeFilter === 'function' && beforeFilter(val)) {
1226	          self.isFiltering = true;
1227	          var nodes = self.getNodes();
1228	          var filterNodes = nodes.filter(function (node) {
1229	            var disabled;
1230	            if (checkStrictly) {
1231	              disabled = node.disabled;
1232	            } else {
1233	              disabled = node.path.some(function (node) {
1234	                return node.disabled;
1235	              });
1236	            }
1237	            if ((node.leaf || checkStrictly) && !disabled) {
1238	              if (typeof filterMethod === 'function' && filterMethod(node, val)) {
1239	                // 命中
1240	                return true;
1241	              }
1242	            }
1243	            return false;
1244	          });
1245	          self._setSuggestionMenu(filterNodes);
1246	        }
1247	      }, debounce);
1248	    }
1249	
1250	    if (multiple) {
1251	      // 多选可搜索
1252	      this.$tagsInput = $('<input type="text" autocomplete="off" placeholder="' + placeholder + '" class="el-cascader__search-input">');
1253	      var $tagsInput = this.$tagsInput;
1254	      this.$tags.append($tagsInput);
1255	      $tagsInput.on('keydown', filter);
1256	      $tagsInput.click(function (event) {
1257	        if (self.isFiltering) {
1258	          stopPropagation(event);
1259	        }
1260	      });
1261	    } else {
1262	      var $inputRow = this.$inputRow;
1263	      // 单选可搜索
1264	      $inputRow.removeAttr('readonly');
1265	      $inputRow.on('keydown', filter);
1266	      $inputRow.click(function (event) {
1267	        if (self.isFiltering) {
1268	          stopPropagation(event);
1269	        }
1270	      });
1271	    }
1272	  },
1273	  // 初始化面板(panel(1))
1274	  _initPanel: function () {
1275	    var $panel = this.$panel;
1276	    var popperClass = this.config.popperClass || '';
1277	    if (!$panel) {
1278	      // z-index:解决和layer.open默认19891016的冲突
1279	      this.$panel = $('<div class="el-popper el-cascader__dropdown ' + popperClass + '" style="position: absolute;
1279 z-index: 109891015;display: none;" x-placement="bottom-start"><div class="el-cascader-panel"></div><div class="popper__arrow" style="left: 35px;"></div></div>');
1280	      $panel = this.$panel;
1281	      $panel.appendTo('body');
1282	      $panel.click(function (event) {
1283	        // 阻止事件冒泡
1284	        stopPropagation(event);
1285	      });
1286	      // 初始化可搜索面板
1287	      this._initSuggestionPanel();
1288	    }
1289	  },
1290	  /**
1291	   * 添加菜单(panel(1)->menu(n))
1292	   * @param nodes 当前层级数据
1293	   * @param level 层级,从0开始
1294	   * @param parentNode 父级节点
1295	   * @param _menuItem 刷新时,传入的当前菜单的item数据
1296	   * @private
1297	   */
1298	  _appendMenu: function (nodes, level, parentNode, _menuItem) {
1299	    this._removeMenu(level);
1300	
1301	    if (parentNode && parentNode.leaf) {
1302	      return;
1303	    }
1304	
1305	    var menuData = this.data.menuData;
1306	    var $div = $('<div class="el-scrollbar el-cascader-menu" role="menu" id="cascader-menu"><div class="el-cascader-menu__wrap el-scrollbar__wrap" style="margin-bottom: -17px; margin-right: -17px;"><ul class="el-scrollbar__view el-cascader-menu__list"></ul></div></div>');
1307	    // 重新添加菜单
1308	    this.$panel.find('.el-cascader-panel').append($div);
1309	    // 渲染细项
1310	    this._appendLi($div, nodes);
1311	    var menuItem = {nodes: nodes, level: level, parentNode: parentNode, scrollbar: {top: 0, left: 0}};
1312	    if (_menuItem) {
1313	      menuItem.scrollbar = _menuItem.scrollbar
1314	    }
1315	    // 渲染滚动条
1316	    this._initScrollbar($div, menuItem);
1317	    // 重新定位面板
1318	    this._resetXY();
1319	    menuData.push(menuItem);
1320	  },
1321	  /**
1322	   * 移除菜单
1323	   * @param level
1324	   * @private
1325	   */
1326	  _removeMenu: function (level) {
1327	    // 除了上一层的所有菜单全部移除
1328	    var number = level - 1;
1329	    if (number !== -1) {
1330	      this.$panel.find('.el-cascader-panel .el-cascader-menu:gt(' + number + ')').remove();
1331	    } else {
1332	      this.$panel.find('.el-cascader-panel .el-cascader-menu').remove();
1333	    }
1334	    // 保存菜单数据
1335	    var menuData = this.data.menuData;
1336	    if (menuData.length > level) {
1337	      menuData.splice(level, menuData.length - level);
1338	    }
1339	  },
1340	  /**
1341	   * 添加细项(panel(1)->menu(n)->li(n))
1342	   * @param $menu 当前菜单对象
1343	   * @param nodes  当前层级数据
1344	   * @private
1345	   */
1346	  _appendLi: function ($menu, nodes) {
1347	    var $list = $menu.find('.el-cascader-menu__list');
1348	    if (!nodes || nodes.length === 0) {
1349	      var isEmpty = this.config.empty;
1350	      $list.append('<div class="el-cascader-menu__empty-text">' + isEmpty + '</div>');
1351	      return;
1352	    }
1353	    $.each(nodes, function (index, node) {
1354	      node.bind($list);
1355	    });
1356	  },
1357	  /**
1358	   * 刷新菜单面板
1359	   */
1360	  refreshMenu: function () {
1361	    // 先复制一个数组,避免刷新菜单时,数组的数据被改变
1362	    var data = this.data.menuData.concat([]);
1363	    var self = this;
1364	    data.forEach(function (data) {
1365	      self._appendMenu(data.nodes, data.level, data.parentNode, data);
1366	    })
1367	  },
1368	  /**
1369	   * 初始化可搜索面板
1370	   * @private
1371	   */
1372	  _initSuggestionPanel: function () {
1373	    var filterable = this.config.filterable;
1374	    if (!filterable) {
1375	      return;
1376	    }
1377	    var $suggestionPanel = this.$suggestionPanel;
1378	    if (!$suggestionPanel) {
1379	      this.$suggestionPanel = $('<div class="el-cascader__suggestion-panel el-scrollbar" style="display: none;"><div class="el-scrollbar__wrap" style="margin-bottom: -17px; margin-right: -17px;"><ul class="el-scrollbar__view el-cascader__suggestion-list" style="min-width: 222px;"></ul></div></div>');
1380	      $suggestionPanel = this.$suggestionPanel;
1381	      this.$panel.find('.popper__arrow').before($suggestionPanel);
1382	      $suggestionPanel.click(function (event) {
1383	        // 阻止事件冒泡
1384	        stopPropagation(event);
1385	      });
1386	    }
1387	  },
1388	  /**
1389	   * 设置可搜索菜单
1390	   * @param nodes
1391	   * @private
1392	   */
1393	  _setSuggestionMenu: function (nodes) {
1394	    var $suggestionPanel = this.$suggestionPanel;
1395	    var $list = $suggestionPanel.find('.el-cascader__suggestion-list');
1396	    $list.empty();
1397	    $suggestionPanel.find('.el-scrollbar__bar').remove();
1398	    if (!nodes || nodes.length === 0) {
1399	      $list.append('<li class="el-cascader__empty-text">无匹配数据</li>');
1400	      return;
1401	    }
1402	    $.each(nodes, function (index, node) {
1403	      node.bindSuggestion($list);
1404	    });
1405	    this._initScrollbar($suggestionPanel, {scrollbar: {top: 0, left: 0}});
1406	    this._resetXY();
1407	  },
1408	  /**
1409	   * 初始化节点数据
1410	   * @param data 原始数据
1411	   * @param level 层级
1412	   * @param parentNode  父级节点
1413	   * @returns {*[]}
1414	   */
1415	  initNodes: function (data, level, parentNode) {
1416	    var nodes = [];
1417	    for (var key in data) {
1418	      var datum = data[key];
1419	      var node = new Node(datum, this, level, parentNode);
1420	      nodes.push(node);
1421	      if (node.children && node.children.length > 0) {
1422	        node.setChildren(this.initNodes(node.children, level + 1, node));
1423	      }
1424	    }
1425	    return nodes;
1426	  },
1427	  /**
1428	   * 设置单选值
1429	   * @param nodeId 节点id
1430	   * @param node   节点对象
1431	   * @private
1432	   */
1433	  _setActiveValue: function (nodeId, node) {
1434	    if (this.data.activeNodeId !== nodeId) {
1435	      var activeNode = this.data.activeNode;
1436	      this.data.activeNodeId = nodeId;
1437	      this.data.activeNode = node;
1438	      activeNode && activeNode.transferParent(function (node) {
1439	        node.syncStyle();
1440	      }, true);
1441	      node && node.transferParent(function (node) {
1442	        node.syncStyle();
1443	      }, true);
1444	      // 填充路径
1445	      this.change(node && node.value, node);
1446	      if (nodeId !== null) {
1447	        this._setClear();
1448	      }
1449	    }
1450	  },
1451	  /**
1452	   * 设置多选值
1453	   * @param nodeIds 值数组
1454	   * @param nodes 节点数组
1455	   * @private
1456	   */
1457	  _setCheckedValue: function (nodeIds, nodes) {
1458	    var checkedNodes = this.data.checkedNodes;
1459	    var maxSize = this.config.maxSize;
1460	    var maxSizeMode;
1461	    if (nodeIds.length > 0 && maxSize !== 0 && nodeIds.length >= maxSize) {
1462	      nodeIds = nodeIds.slice(0, maxSize);
1463	      nodes = nodes.slice(0, maxSize);
1464	      maxSizeMode = true
1465	    } else {
1466	      maxSizeMode = false
1467	    }
1468	    this.data.checkedNodeIds = nodeIds || [];
1469	    this.data.checkedNodes = nodes || [];
1470	    var syncPath = [];
1471	    var syncNodeIds = [];
1472	    checkedNodes.forEach(function (node) {
1473	      node.path.forEach(function (node) {
1474	        if (syncNodeIds.indexOf(node.nodeId) === -1) {
1475	          syncPath.push(node);
1476	          syncNodeIds.push(node.nodeId);
1477	        }
1478	      });
1479	    });
1480	    nodes.forEach(function (node) {
1481	      node.path.forEach(function (node) {
1482	        if (syncNodeIds.indexOf(node.nodeId) === -1) {
1483	          syncPath.push(node);
1484	          syncNodeIds.push(node.nodeId);
1485	        }
1486	      });
1487	    });
1488	    syncPath.forEach(function (node) {
1489	      node.syncStyle();
1490	    });
1491	    // 填充路径
1492	    this.change(nodes.map(function (node) {
1493	      return node.value;
1494	    }), nodes);
1495	    this._setClear();
1496	    this.maxSizeMode = maxSizeMode;
1497	  },
1498	  /**
1499	   * 设置值
1500	   * @param value
1501	   */
1502	  setValue: function (value) {
1503	    if (this.data.activeNodeId || this.data.checkedNodeIds.length > 0) {
1504	      // 清空值
1505	      this.clearCheckedNodes();
1506	    }
1507	    if (!value) {
1508	      return;
1509	    }
1510	    var strictMode = this.props.strictMode;
1511	    if (strictMode) {
1512	      if (!Array.isArray(value)) {
1513	        throw new Error("严格模式下,value必须是一个包含父子节点数组结构.");
1514	      }
1515	    }
1516	    var nodes = this.getNodes(this.data.nodes);
1517	    var checkStrictly = this.props.checkStrictly;
1518	    var multiple = this.props.multiple;
1519	    var disabledFixed = this.config.disabledFixed;
1520	    if (multiple) {
1521	      var paths = nodes.filter(function (node) {
1522	        if ((checkStrictly || node.leaf) && (!node.disabled || disabledFixed)) {
1523	          if (strictMode) {
1524	            // 严格模式下
1525	            // some:命中一个就为true
1526	            // every:全部命中为true
1527	            return value.some(function (levelValue) {
1528	              if (!Array.isArray(levelValue)) {
1529	                throw new Error("多选严格模式下,value必须是一个二维数组结构.");
1530	              }
1531	              var path = node.path;
1532	              return levelValue.length === path.length && levelValue.every(function (rowValue, index) {
1533	                return path[index].value === rowValue;
1534	              });
1535	            })
1536	          } else {
1537	            return value.indexOf(node.value) !== -1;
1538	          }
1539	        }
1540	        return false;
1541	      });
1542	      var nodeIds = paths.map(function (node) {
1543	        return node.nodeId;
1544	      });
1545	      this._setCheckedValue(nodeIds, paths);
1546	      // 展开第一个节点
1547	      if (paths.length > 0) {
1548	        var first = paths[0];
1549	        first.expandPanel();
1550	      }
1551	    } else {
1552	      for (var i = 0; i < nodes.length; i++) {
1553	        var node = nodes[i];
1554	        if ((checkStrictly || node.leaf)) {
1555	          var is = false;
1556	          if (strictMode) {
1557	            // 严格模式下
1558	            // every:全部命中为true
1559	            var path = node.path;
1560	            is = value.length === path.length && value.every(function (rowValue, index) {
1561	              return path[index].value === rowValue;
1562	            });
1563	          } else if (node.value === value) {
1564	            is = true;
1565	          }
1566	          if (is) {
1567	            this._setActiveValue(node.nodeId, node);
1568	            // 展开节点
1569	            node.expandPanel();
1570	            break;
1571	          }
1572	        }
1573	      }
1574	    }
1575	  },
1576	  /**
1577	   * 递归获取扁平的节点
1578	   * @param nodes
1579	   * @param container
1580	   * @returns {*[]}
1581	   */
1582	  getNodes: function (nodes, container) {
1583	    if (!container) {
1584	      container = [];
1585	    }
1586	    if (!nodes) {
1587	      nodes = this.data.nodes;
1588	    }
1589	    var self = this;
1590	    nodes.forEach(function (node) {
1591	      container.push(node);
1592	      var children = node.getChildren();
1593	      if (children) {
1594	        self.getNodes(children, container);
1595	      }
1596	    });
1597	    return container;
1598	  },
1599	  /**
1600	   * 初始化滚动条
1601	   * @param $menu   菜单的dom节点对象
1602	   * @param menuItem 当前菜单数据
1603	   * @private
1604	   */
1605	  _initScrollbar: function ($menu, menuItem) {
1606	    var $div = $('<div class="el-scrollbar__bar is-onhoriztal"><div class="el-scrollbar__thumb" style="transform: translateX(0%);"></div></div><div class="el-scrollbar__bar is-vertical"><div class="el-scrollbar__thumb" style="transform: translateY(0%);"></div></div>');
1607	    $menu.append($div);
1608	    var vertical = $($div[1]).find('.el-scrollbar__thumb');
1609	    var onhoriztal = $($div[0]).find('.el-scrollbar__thumb');
1610	    var scrollbar = $menu.find('.el-scrollbar__wrap');
1611	    var $panel = this.$panel;
1612	    var $lis = $menu.find('li');
1613	    var height = Math.max($panel.height(), $menu.height());
1614	    var hScale = (height - 6) / ($lis.height() * $lis.length);
1615	    var wScale = $panel.width() / $lis.width();
1616	
1617	    // 滚动条监听事件
1618	    function _scrollbarEvent(scrollTop, scrollLeft) {
1619	      if (hScale < 1) {
1620	        vertical.css('height', hScale * 100 + '%');
1621	        vertical.css('transform', 'translateY(' + scrollTop / $menu.height() * 100 + '%)');
1622	      }
1623	      if (wScale < 1) {
1624	        onhoriztal.css('width', wScale * 100 + '%');
1625	        onhoriztal.css('transform', 'translateY(' + scrollLeft / $menu.width() * 100 + '%)');
1626	      }
1627	    }
1628	
1629	    // 拖动事件
1630	    vertical.mousedown(function (event) {
1631	      event.stopImmediatePropagation();
1632	      stopPropagation(event);
1633	      // 禁止文本选择事件
1634	      var selectstart = function () {
1635	        return false;
1636	      };
1637	      $(document).bind("selectstart", selectstart);
1638	      var y = event.clientY;
1639	      var scrollTop = scrollbar.scrollTop();
1640	      // 移动事件
1641	      var mousemove = function (event) {
1642	        event.stopImmediatePropagation();
1643	        var number = scrollTop + (event.clientY - y) / hScale;
1644	        scrollbar.scrollTop(number);
1645	      };
1646	      $(document).bind('mousemove', mousemove);
1647	      // 鼠标松开事件
1648	      $(document).one('mouseup', function (event) {
1649	        stopPropagation(event);
1650	        event.stopImmediatePropagation();
1651	        $(document).off('mousemove', mousemove);
1652	        $(document).off('selectstart', selectstart);
1653	      });
1654	    });
1655	    // 监听滚动条事件
1656	    scrollbar.scroll(function () {
1657	      var scroll = $(this);
1658	      menuItem.scrollbar.top = scroll.scrollTop()
1659	      menuItem.scrollbar.left = scroll.scrollLeft()
1660	      _scrollbarEvent(menuItem.scrollbar.top, menuItem.scrollbar.left);
1661	    });
1662	
1663	    // 初始化滚动条
1664	    scrollbar.scrollTop(menuItem.scrollbar.top);
1665	    _scrollbarEvent(menuItem.scrollbar.top, menuItem.scrollbar.left);
1666	  },
1667	  // 填充路径
1668	  _fillingPath: function () {
1669	    var multiple = this.props.multiple;
1670	    var showAllLevels = this.config.showAllLevels;
1671	    var separator = this.config.separator;
1672	    var collapseTags = this.config.collapseTags;
1673	    var $inputRow = this.$inputRow;
1674	    var placeholder = this.config.placeholder;
1675	    var self = this;
1676	    if (!multiple) {
1677	      var activeNode = this.data.activeNode;
1678	      var path = activeNode && activeNode.path || [];
1679	      if (showAllLevels) {
1680	        this._$inputRowSetValue(path.map(function (node) {
1681	          return node.label;
1682	        }).join(separator));
1683	      } else {
1684	        this._$inputRowSetValue(activeNode && activeNode.label || "");
1685	      }
1686	    } else {
1687	      // 复选框
1688	
1689	      // 删除标签
1690	      this.$tags.find('.el-tag').remove();
1691	      var $tagsInput = this.$tagsInput;
1692	      // 清除高度
1693	      $inputRow.css('height', '');
1694	      var checkedNodes = this.data.checkedNodes;
1695	      var minCollapseTagsNumber = Math.max(this.config.minCollapseTagsNumber, 1);
1696	      if (checkedNodes.length > 0) {
1697	        var tags = [];
1698	        var paths = checkedNodes;
1699	        if (collapseTags) {
1700	          // 折叠tags
1701	          paths = checkedNodes.slice(0, Math.min(checkedNodes.length, minCollapseTagsNumber));
1702	        }
1703	        paths.forEach(function (node) {
1704	          tags.push(node.$tag);
1705	        });
1706	        // 判断标签是否折叠
1707	        if (collapseTags) {
1708	          // 判断标签最小折叠数
1709	          if (checkedNodes.length > minCollapseTagsNumber) {
1710	            tags.push(self.get$tag('+ ' + (checkedNodes.length - minCollapseTagsNumber), false));
1711	          }
1712	        }
1713	        tags.forEach(function (tag) {
1714	          if ($tagsInput) {
1715	            $tagsInput.before(tag)
1716	          } else {
1717	            self.$tags.append(tag);
1718	          }
1719	        });
1720	      }
1721	      var tagHeight = self.$tags.height();
1722	      var inputHeight = $inputRow.height();
1723	      if (tagHeight > inputHeight) {
1724	        $inputRow.css('height', tagHeight + 4 + 'px');
1725	      }
1726	      // 重新定位
1727	      this._resetXY();
1728	      if (checkedNodes.length > 0) {
1729	        $inputRow.removeAttr('placeholder');
1730	        $tagsInput && $tagsInput.removeAttr('placeholder', placeholder);
1731	      } else {
1732	        $inputRow.attr('placeholder', placeholder);
1733	        $tagsInput && $tagsInput.attr('placeholder', placeholder);
1734	      }
1735	    }
1736	  },
1737	  /**
1738	   * 设置单选输入框的值
1739	   * @param label
1740	   * @private
1741	   */
1742	  _$inputRowSetValue: function (label) {
1743	    label = label || "";
1744	    var $inputRow = this.$inputRow;
1745	    $inputRow.attr('value', label); //防止被重置
1746	    $inputRow.val(label);
1747	  },
1748	  /**
1749	   * 获取复选框标签对象
1750	   * @param label
1751	   * @param showCloseIcon 是否显示关闭的icon
1752	   * @returns {jQuery|HTMLElement|*}
1753	   */
1754	  get$tag: function (label, showCloseIcon) {
1755	    var fromIcon = this.icons.from;
1756	    var closeIcon = this.icons.close;
1757	    var icon = showCloseIcon ? '<i class="el-tag__close el-icon-close ' + fromIcon + ' ' + closeIcon + '"></i>' : '';
1758	    return $('<span class="el-tag el-tag--info el-tag--small el-tag--light"><span>' + label + '</span>' + icon + '</span>');
1759	  },
1760	  // 设置可清理
1761	  _setClear: function () {
1762	    var self = this;
1763	
1764	    function enter() {
1765	      self.$icon.removeClass(self.icons.down);
1766	      self.$icon.addClass(self.icons.close);
1767	    }
1768	
1769	    function out() {
1770	      self.$icon.removeClass(self.icons.close);
1771	      self.$icon.addClass(self.icons.down);
1772	    }
1773	
1774	    self.$div.mouseenter(function () {
1775	      enter();
1776	    });
1777	    self.$div.mouseleave(function () {
1778	      out();
1779	    });
1780	    self.$icon.off('click');
1781	    var multiple = this.props.multiple;
1782	    var clear;
1783	    if (multiple) {
1784	      clear = this.data.checkedNodeIds.length > 0;
1785	    } else {
1786	      clear = !!this.data.activeNodeId;
1787	    }
1788	    if (clear && !this.config.disabled && this.config.clearable) {
1789	      self.$icon.one('click', function (event) {
1790	        stopPropagation(event);
1791	        self.close();
1792	        self.clearCheckedNodes();
1793	        out();
1794	        self.$icon.off('mouseenter');
1795	        self.$div.off('mouseenter');
1796	        self.$div.off('mouseleave');
1797	      });
1798	    } else {
1799	      out();
1800	      self.$icon.off('mouseenter');
1801	      self.$div.off('mouseenter');
1802	      self.$div.off('mouseleave');
1803	    }
1804	  },
1805	  // 禁用
1806	  disabled: function (isDisabled) {
1807	    this.config.disabled = !!isDisabled;
1808	    if (this.config.disabled) {
1809	      this.$div.addClass('is-disabled');
1810	      this.$div.find('.el-input--suffix').addClass('is-disabled');
1811	      this.$inputRow.attr('disabled', 'disabled');
1812	      this.$tagsInput && this.$tagsInput.attr('disabled', 'disabled').hide()
1813	    } else {
1814	      this.$div.removeClass('is-disabled');
1815	      this.$div.find('.el-input--suffix').removeClass('is-disabled');
1816	      this.$inputRow.removeAttr('disabled');
1817	      this.$tagsInput && this.$tagsInput.removeAttr('disabled').show();
1818	    }
1819	    // 重新设置是否可被清理
1820	    this._setClear();
1821	    // 重新填充路径
1822	    this._fillingPath();
1823	  },
1824	  /**
1825	   * 当选中节点变化时触发  选中节点的值
1826	   * @param value 值
1827	   * @param node  节点
1828	   */
1829	  change: function (value, node) {
1830	    var multiple = this.props.multiple;
1831	    if (multiple) {
1832	      if (value && value.length > 0) {
1833	        this.$ec.attr('value', JSON.stringify(value));
1834	        // this.$ec.val(JSON.stringify(value));
1835	      } else {
1836	        this.$ec.removeAttr('value');
1837	        // this.$ec.val('');
1838	      }
1839	    } else {
1840	      this.$ec.attr('value', value || "");
1841	      // this.$ec.val(value);
1842	    }
1843	    // 填充路径
1844	    this._fillingPath();
1845	    this.event.change.forEach(function (e) {
1846	      typeof e === 'function' && e(value, node)
1847	    })
1848	  },
1849	  /**
1850	   * 当失去焦点时触发  (event: Event)
1851	   * @param eventId 不为空时,必须与closeEventId值相等,防止旧事件触发
1852	   */
1853	  close: function (eventId) {
1854	    if (this.showPanel && (!eventId || this.closeEventId === eventId)) {
1855	      this.showPanel = false;
1856	      this.$div.find('.layui-icon-down').removeClass('is-reverse');
1857	      this.$panel.slideUp(100);
1858	      this.visibleChange(false);
1859	      // 聚焦颜色
1860	      this.$input.removeClass('is-focus');
1861	      // 可搜索
1862	      var filterable = this.config.filterable;
1863	      if (filterable) {
1864	        this.isFiltering = false;
1865	        this._fillingPath();
1866	      }
1867	      this.event.close.forEach(function (e) {
1868	        typeof e === 'function' && e()
1869	      })
1870	    }
1871	  },
1872	  /**
1873	   * 当获得焦点时触发  (event: Event)
1874	   */
1875	  open: function () {
1876	    if (!this.showPanel) {
1877	      this.showPanel = true;
1878	      this.closeEventId++;
1879	      var self = this;
1880	      // 当前传播事件结束后,添加点击背景关闭面板事件
1881	      setTimeout(function () {
1882	        $(document).one('click', self.close.bind(self, self.closeEventId));
1883	      });
1884	      // 重新定位面板
1885	      this._resetXY();
1886	      // 箭头icon翻转
1887	      this.$div.find('.layui-icon-down').addClass('is-reverse');
1888	      this.$panel.slideDown(200);
1889	      this.visibleChange(true);
1890	      // 聚焦颜色
1891	      this.$input.addClass('is-focus');
1892	      this.event.open.forEach(function (e) {
1893	        typeof e === 'function' && e()
1894	      })
1895	    }
1896	  },
1897	  /**
1898	   * 下拉框出现/隐藏时触发
1899	   * @param visible 出现则为 true,隐藏则为 false
1900	   */
1901	  visibleChange: function (visible) {
1902	  },
1903	  /**
1904	   * 在多选模式下,移除Tag时触发  移除的Tag对应的节点的值
1905	   * @param tagValue 节点的值
1906	   * @param node 节点对象
1907	   */
1908	  removeTag: function (tagValue, node) {
1909	  },
1910	  /**
1911	   * 获取选中的节点值
1912	   * @returns {null|[]}
1913	   */
1914	  getCheckedValues: function () {
1915	    var strictMode = this.props.strictMode;
1916	    if (this.props.multiple) {
1917	      var checkedNodes = this.data.checkedNodes;
1918	      if (strictMode) {
1919	        return checkedNodes.map(function (node) {
1920	          return node.path.map(function (node1) {
1921	            return node1.value;
1922	          });
1923	        });
1924	      }
1925	      return checkedNodes.map(function (node) {
1926	        return node.value;
1927	      });
1928	    } else {
1929	      var activeNode = this.data.activeNode;
1930	      if (strictMode) {
1931	        return activeNode && activeNode.path.map(function (node) {
1932	          return node.value;
1933	        })
1934	      }
1935	      return activeNode && activeNode.value;
1936	    }
1937	  },
1938	  /**
1939	   * 获取选中的节点
1940	   * @returns {null|[]}
1941	   */
1942	  getCheckedNodes: function () {
1943	    var strictMode = this.props.strictMode;
1944	    if (this.props.multiple) {
1945	      var checkedNodes = this.data.checkedNodes;
1946	      if (strictMode) {
1947	        return checkedNodes && checkedNodes.map(function (node) {
1948	          return node.path;
1949	        });
1950	      }
1951	      return checkedNodes;
1952	    } else {
1953	      var activeNode = this.data.activeNode;
1954	      if (strictMode) {
1955	        return activeNode && activeNode.path;
1956	      }
1957	      return activeNode;
1958	    }
1959	  },
1960	  /**
1961	   * 清空选中的节点
1962	   * @param force 强制清理禁用固定节点
1963	   */
1964	  clearCheckedNodes: function (force) {
1965	    var multiple = this.props.multiple;
1966	    if (multiple) {
1967	      var disabledFixed = this.config.disabledFixed;
1968	      if (!force && disabledFixed) {
1969	        //禁用项被固定,则过滤出禁用项的选值出来
1970	        var checkedNodes = this.data.checkedNodes;
1971	        var disNodes = checkedNodes.filter(function (node) {
1972	          return node.disabled;
1973	        });
1974	        var nodeIds = disNodes.map(function (node) {
1975	          return node.nodeId;
1976	        });
1977	        this._setCheckedValue(nodeIds, disNodes);
1978	      } else {
1979	        this._setCheckedValue([], []);
1980	      }
1981	    } else {
1982	      this._setActiveValue(null, null);
1983	    }
1984	  },
1985		/**
1986		 * 当节点变更时,执行回调
1987		 * @param callback  function(value,node){}
1988		 */
1989		changeEvent: function (callback) {
1990		  this.event.change.push(callback);
1991		},
1992		/**
1993		 * 当面板打开时,执行回调
1994		 * @param callback  function(){}
1995		 */
1996		openEvent: function (callback) {
1997		  this.event.open.push(callback);
1998		},
1999		/**
2000		 * 当面板关闭时,执行回调
2001		 * @param callback  function(){}
2002		 */
2003		closeEvent: function (callback) {
2004		  this.event.close.push(callback);
2005		},
2006	};
2007	
2008	var thisCas = function () {
2009	  var self = this;
2010	  return {
2011	    /**
2012	     * 设置选项值
2013	     * @param options
2014	     */
2015	    setOptions: function (options) {
2016	      self.setOptions(options);
2017	    },
2018	    /**
2019	     * 覆盖当前值
2020	     * @param value 单选时传对象,多选时传数组
2021	     */
2022	    setValue: function (value) {
2023	      self.setValue(value);
2024	    },
2025	    /**
2026	     * 禁用组件
2027	     * @param disabled true/false
2028	     */
2029	    disabled: function (disabled) {
2030	      self.disabled(disabled);
2031	    },
2032	    /**
2033	     * 收起面板
2034	     */
2035	    close: function () {
2036	      self.close();
2037	    },
2038	    /**
2039	     * 展开面板
2040	     */
2041	    open: function () {
2042	      self.open();
2043	    },
2044	    /**
2045	     * 获取选中的节点,如需获取路径,使用node.path获取,将获取各级节点的node对象
2046	     * @returns {[]|*}
2047	     */
2048	    getCheckedNodes: function () {
2049	      return self.getCheckedNodes();
2050	    },
2051	    /**
2052	     * 获取选中的值
2053	     * @returns {[]|*}
2054	     */
2055	    getCheckedValues: function () {
2056	      return self.getCheckedValues();
2057	    },
2058	    /**
2059	     * 清空选中的节点
2060	     * @param force 强制清理禁用固定节点
2061	     */
2062	    clearCheckedNodes: function (force) {
2063	      self.clearCheckedNodes(force);
2064	    },
2065	    /**
2066	     * 展开面板到节点所在的层级
2067	     * @param value 节点值,只能传单个值,不允许传数组
2068	     */
2069	    expandNode: function (value) {
2070	      var nodes = self.getNodes(self.data.nodes);
2071	      for (var i = 0; i < nodes.length; i++) {
2072	        var node = nodes[i];
2073	        if (node.value === value) {
2074	          node.expandPanel();
2075	          break;
2076	        }
2077	      }
2078	    },
2079	    /**
2080	     * 获取当前配置副本
2081	     */
2082	    getConfig: function () {
2083	      return $.extend(true, {}, self.config);
2084	    },
2085	    /**
2086	     * 获取数据对象副本
2087	     * @returns {*}
2088	     */
2089	    getData: function () {
2090	      return $.extend(true, {}, self.data);
2091	    }
2092	  };
2093	};
2094	window.Cascader=Cascader;
2095})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.