umy-ui-table 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/lib/button.js +1 -0
  4. package/lib/icon.js +1 -0
  5. package/lib/index.js +1 -0
  6. package/lib/locale/format.js +56 -0
  7. package/lib/locale/index.js +72 -0
  8. package/lib/locale/lang/en.js +123 -0
  9. package/lib/locale/lang/zh-CN.js +119 -0
  10. package/lib/mixins/locale.js +17 -0
  11. package/lib/theme-chalk/base.css +0 -0
  12. package/lib/theme-chalk/button.css +1 -0
  13. package/lib/theme-chalk/fonts/element-icons.ttf +0 -0
  14. package/lib/theme-chalk/fonts/element-icons.woff +0 -0
  15. package/lib/theme-chalk/fonts/iconfont.1785562768224.ttf +0 -0
  16. package/lib/theme-chalk/fonts/iconfont.1785562768224.woff +0 -0
  17. package/lib/theme-chalk/fonts/iconfont.1785562768224.woff2 +0 -0
  18. package/lib/theme-chalk/icon.css +1 -0
  19. package/lib/theme-chalk/index.css +1 -0
  20. package/lib/theme-chalk/u-table-column.css +0 -0
  21. package/lib/theme-chalk/u-table.css +1 -0
  22. package/lib/theme-chalk/ux-grid.css +1 -0
  23. package/lib/theme-chalk/ux-table-column.css +0 -0
  24. package/lib/u-table-column.js +1 -0
  25. package/lib/u-table.js +1 -0
  26. package/lib/umd/locale/en.js +139 -0
  27. package/lib/umd/locale/zh-CN.js +135 -0
  28. package/lib/umy-ui.common.js +1 -0
  29. package/lib/utils/svg.js +33 -0
  30. package/lib/utils/types.js +35 -0
  31. package/lib/utils/util.js +268 -0
  32. package/lib/ux-grid.js +1 -0
  33. package/lib/ux-table-column.js +1 -0
  34. package/package.json +117 -0
  35. package/packages/button/index.js +7 -0
  36. package/packages/button/src/button-group.vue +10 -0
  37. package/packages/button/src/button.vue +166 -0
  38. package/packages/checkbox/index.js +8 -0
  39. package/packages/checkbox/src/checkbox-button.vue +199 -0
  40. package/packages/checkbox/src/checkbox-group.vue +48 -0
  41. package/packages/checkbox/src/checkbox.vue +222 -0
  42. package/packages/checkbox-button/index.js +8 -0
  43. package/packages/checkbox-group/index.js +8 -0
  44. package/packages/icon/index.js +7 -0
  45. package/packages/icon/src/icon.vue +40 -0
  46. package/packages/input/index.js +2 -0
  47. package/packages/input/src/calcTextareaHeight.js +104 -0
  48. package/packages/input/src/input.vue +424 -0
  49. package/packages/option/index.js +2 -0
  50. package/packages/pagination/index.js +2 -0
  51. package/packages/pagination/src/pager.vue +163 -0
  52. package/packages/pagination/src/pagination.js +386 -0
  53. package/packages/scrollbar/index.js +8 -0
  54. package/packages/scrollbar/src/bar.js +92 -0
  55. package/packages/scrollbar/src/main.js +130 -0
  56. package/packages/scrollbar/src/util.js +34 -0
  57. package/packages/select/index.js +2 -0
  58. package/packages/select/src/navigation-mixin.js +54 -0
  59. package/packages/select/src/option-group.vue +60 -0
  60. package/packages/select/src/option.vue +163 -0
  61. package/packages/select/src/select-dropdown.vue +74 -0
  62. package/packages/select/src/select.vue +889 -0
  63. package/packages/table/index.js +8 -0
  64. package/packages/table/src/config.js +123 -0
  65. package/packages/table/src/dropdown.js +28 -0
  66. package/packages/table/src/filter-panel.vue +194 -0
  67. package/packages/table/src/layout-observer.js +68 -0
  68. package/packages/table/src/store/current.js +71 -0
  69. package/packages/table/src/store/expand.js +65 -0
  70. package/packages/table/src/store/helper.js +37 -0
  71. package/packages/table/src/store/index.js +145 -0
  72. package/packages/table/src/store/tree.js +208 -0
  73. package/packages/table/src/store/watcher.js +448 -0
  74. package/packages/table/src/table-body.js +493 -0
  75. package/packages/table/src/table-column.js +381 -0
  76. package/packages/table/src/table-footer.js +174 -0
  77. package/packages/table/src/table-header.js +537 -0
  78. package/packages/table/src/table-layout.js +231 -0
  79. package/packages/table/src/table.vue +741 -0
  80. package/packages/table/src/util.js +256 -0
  81. package/packages/tag/index.js +8 -0
  82. package/packages/tag/src/tag.vue +58 -0
  83. package/packages/tools/directives/mousewheel.js +18 -0
  84. package/packages/tools/directives/repeat-click.js +24 -0
  85. package/packages/tools/locale/format.js +46 -0
  86. package/packages/tools/locale/index.js +48 -0
  87. package/packages/tools/locale/lang/en.js +120 -0
  88. package/packages/tools/locale/lang/zh-CN.js +116 -0
  89. package/packages/tools/mixins/emitter.js +33 -0
  90. package/packages/tools/mixins/focus.js +9 -0
  91. package/packages/tools/mixins/locale.js +9 -0
  92. package/packages/tools/mixins/migrating.js +54 -0
  93. package/packages/tools/transitions/collapse-transition.js +77 -0
  94. package/packages/tools/utils/after-leave.js +27 -0
  95. package/packages/tools/utils/aria-dialog.js +90 -0
  96. package/packages/tools/utils/aria-utils.js +122 -0
  97. package/packages/tools/utils/clickoutside.js +76 -0
  98. package/packages/tools/utils/date-util.js +292 -0
  99. package/packages/tools/utils/date.js +368 -0
  100. package/packages/tools/utils/dom.js +227 -0
  101. package/packages/tools/utils/menu/aria-menubar.js +14 -0
  102. package/packages/tools/utils/menu/aria-menuitem.js +49 -0
  103. package/packages/tools/utils/menu/aria-submenu.js +59 -0
  104. package/packages/tools/utils/merge.js +15 -0
  105. package/packages/tools/utils/popper.js +1276 -0
  106. package/packages/tools/utils/popup/index.js +218 -0
  107. package/packages/tools/utils/popup/popup-manager.js +194 -0
  108. package/packages/tools/utils/resize-event.js +35 -0
  109. package/packages/tools/utils/scroll-into-view.js +27 -0
  110. package/packages/tools/utils/scrollbar-width.js +29 -0
  111. package/packages/tools/utils/shared.js +7 -0
  112. package/packages/tools/utils/svg.js +1 -0
  113. package/packages/tools/utils/types.js +28 -0
  114. package/packages/tools/utils/util.js +241 -0
  115. package/packages/tools/utils/vdom.js +5 -0
  116. package/packages/tools/utils/vue-popper.js +198 -0
  117. package/packages/tooltip/index.js +8 -0
  118. package/packages/tooltip/src/main.js +241 -0
  119. package/packages/u-table/index.js +4 -0
  120. package/packages/u-table/revise-el-table-mixins/index.js +10 -0
  121. package/packages/u-table/revise-el-table-mixins/table-extend.js +60 -0
  122. package/packages/u-table/revise-el-table-mixins/table.mixins.js +261 -0
  123. package/packages/u-table/revise-el-table-mixins/virtual-table-body-render.js +132 -0
  124. package/packages/u-table/src/u-table.vue +248 -0
  125. package/packages/u-table/u-table-mixins/index.js +483 -0
  126. package/packages/u-table/u-table-tree-mixins/methods.js +120 -0
  127. package/packages/u-table/u-table-tree-mixins/u-table-tree-mixins.js +161 -0
  128. package/packages/u-table-column/index.js +8 -0
  129. package/packages/utils/common.js +27 -0
  130. package/packages/ux-grid/index.js +6 -0
  131. package/packages/ux-grid/mixins/index.js +707 -0
  132. package/packages/ux-grid/src/interceptor.js +6 -0
  133. package/packages/ux-grid/src/ux-grid.vue +301 -0
  134. package/packages/ux-table-column/index.js +10 -0
  135. package/tools/locale/format.js +46 -0
  136. package/tools/locale/index.js +54 -0
  137. package/tools/locale/lang/en.js +120 -0
  138. package/tools/locale/lang/zh-CN.js +116 -0
  139. package/tools/mixins/locale.js +9 -0
  140. package/tools/utils/svg.js +1 -0
  141. package/tools/utils/types.js +28 -0
  142. package/tools/utils/util.js +241 -0
@@ -0,0 +1,33 @@
1
+ function broadcast(componentName, eventName, params) {
2
+ this.$children.forEach(child => {
3
+ var name = child.$options.componentName;
4
+
5
+ if (name === componentName) {
6
+ child.$emit.apply(child, [eventName].concat(params));
7
+ } else {
8
+ broadcast.apply(child, [componentName, eventName].concat([params]));
9
+ }
10
+ });
11
+ }
12
+ export default {
13
+ methods: {
14
+ dispatch(componentName, eventName, params) {
15
+ var parent = this.$parent || this.$root;
16
+ var name = parent.$options.componentName;
17
+
18
+ while (parent && (!name || name !== componentName)) {
19
+ parent = parent.$parent;
20
+
21
+ if (parent) {
22
+ name = parent.$options.componentName;
23
+ }
24
+ }
25
+ if (parent) {
26
+ parent.$emit.apply(parent, [eventName].concat(params));
27
+ }
28
+ },
29
+ broadcast(componentName, eventName, params) {
30
+ broadcast.call(this, componentName, eventName, params);
31
+ }
32
+ }
33
+ };
@@ -0,0 +1,9 @@
1
+ export default function(ref) {
2
+ return {
3
+ methods: {
4
+ focus() {
5
+ this.$refs[ref].focus();
6
+ }
7
+ }
8
+ };
9
+ };
@@ -0,0 +1,9 @@
1
+ import { t } from '../locale';
2
+
3
+ export default {
4
+ methods: {
5
+ t(...args) {
6
+ return t.apply(this, args);
7
+ }
8
+ }
9
+ };
@@ -0,0 +1,54 @@
1
+ import { kebabCase } from '../utils/util';
2
+ /**
3
+ * Show migrating guide in browser console.
4
+ *
5
+ * Usage:
6
+ * import Migrating from 'umy-table/tools/mixins/migrating';
7
+ *
8
+ * mixins: [Migrating]
9
+ *
10
+ * add getMigratingConfig method for your component.
11
+ * getMigratingConfig() {
12
+ * return {
13
+ * props: {
14
+ * 'allow-no-selection': 'allow-no-selection is removed.',
15
+ * 'selection-mode': 'selection-mode is removed.'
16
+ * },
17
+ * events: {
18
+ * selectionchange: 'selectionchange is renamed to selection-change.'
19
+ * }
20
+ * };
21
+ * },
22
+ */
23
+ export default {
24
+ mounted() {
25
+ if (process.env.NODE_ENV === 'production') return;
26
+ if (!this.$vnode) return;
27
+ const { props = {}, events = {} } = this.getMigratingConfig();
28
+ const { data, componentOptions } = this.$vnode;
29
+ const definedProps = data.attrs || {};
30
+ const definedEvents = componentOptions.listeners || {};
31
+
32
+ for (let propName in definedProps) {
33
+ propName = kebabCase(propName); // compatible with camel case
34
+ if (props[propName]) {
35
+ console.warn(`[Element Migrating][${this.$options.name}][Attribute]: ${props[propName]}`);
36
+ }
37
+ }
38
+
39
+ for (let eventName in definedEvents) {
40
+ eventName = kebabCase(eventName); // compatible with camel case
41
+ if (events[eventName]) {
42
+ console.warn(`[Element Migrating][${this.$options.name}][Event]: ${events[eventName]}`);
43
+ }
44
+ }
45
+ },
46
+ methods: {
47
+ getMigratingConfig() {
48
+ return {
49
+ props: {},
50
+ events: {}
51
+ };
52
+ }
53
+ }
54
+ };
@@ -0,0 +1,77 @@
1
+ import { addClass, removeClass } from '../utils/dom';
2
+
3
+ class Transition {
4
+ beforeEnter(el) {
5
+ addClass(el, 'collapse-transition');
6
+ if (!el.dataset) el.dataset = {};
7
+
8
+ el.dataset.oldPaddingTop = el.style.paddingTop;
9
+ el.dataset.oldPaddingBottom = el.style.paddingBottom;
10
+
11
+ el.style.height = '0';
12
+ el.style.paddingTop = 0;
13
+ el.style.paddingBottom = 0;
14
+ }
15
+
16
+ enter(el) {
17
+ el.dataset.oldOverflow = el.style.overflow;
18
+ if (el.scrollHeight !== 0) {
19
+ el.style.height = el.scrollHeight + 'px';
20
+ el.style.paddingTop = el.dataset.oldPaddingTop;
21
+ el.style.paddingBottom = el.dataset.oldPaddingBottom;
22
+ } else {
23
+ el.style.height = '';
24
+ el.style.paddingTop = el.dataset.oldPaddingTop;
25
+ el.style.paddingBottom = el.dataset.oldPaddingBottom;
26
+ }
27
+
28
+ el.style.overflow = 'hidden';
29
+ }
30
+
31
+ afterEnter(el) {
32
+ // for safari: remove class then reset height is necessary
33
+ removeClass(el, 'collapse-transition');
34
+ el.style.height = '';
35
+ el.style.overflow = el.dataset.oldOverflow;
36
+ }
37
+
38
+ beforeLeave(el) {
39
+ if (!el.dataset) el.dataset = {};
40
+ el.dataset.oldPaddingTop = el.style.paddingTop;
41
+ el.dataset.oldPaddingBottom = el.style.paddingBottom;
42
+ el.dataset.oldOverflow = el.style.overflow;
43
+
44
+ el.style.height = el.scrollHeight + 'px';
45
+ el.style.overflow = 'hidden';
46
+ }
47
+
48
+ leave(el) {
49
+ if (el.scrollHeight !== 0) {
50
+ // for safari: add class after set height, or it will jump to zero height suddenly, weired
51
+ addClass(el, 'collapse-transition');
52
+ el.style.height = 0;
53
+ el.style.paddingTop = 0;
54
+ el.style.paddingBottom = 0;
55
+ }
56
+ }
57
+
58
+ afterLeave(el) {
59
+ removeClass(el, 'collapse-transition');
60
+ el.style.height = '';
61
+ el.style.overflow = el.dataset.oldOverflow;
62
+ el.style.paddingTop = el.dataset.oldPaddingTop;
63
+ el.style.paddingBottom = el.dataset.oldPaddingBottom;
64
+ }
65
+ }
66
+
67
+ export default {
68
+ name: 'ElCollapseTransition',
69
+ functional: true,
70
+ render(h, { children }) {
71
+ const data = {
72
+ on: new Transition()
73
+ };
74
+
75
+ return h('transition', data, children);
76
+ }
77
+ };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Bind after-leave event for vue instance. Make sure after-leave is called in any browsers.
3
+ *
4
+ * @param {Vue} instance Vue instance.
5
+ * @param {Function} callback callback of after-leave event
6
+ * @param {Number} speed the speed of transition, default value is 300ms
7
+ * @param {Boolean} once weather bind after-leave once. default value is false.
8
+ */
9
+ export default function(instance, callback, speed = 300, once = false) {
10
+ if (!instance || !callback) throw new Error('instance & callback is required');
11
+ let called = false;
12
+ const afterLeaveCallback = function() {
13
+ if (called) return;
14
+ called = true;
15
+ if (callback) {
16
+ callback.apply(null, arguments);
17
+ }
18
+ };
19
+ if (once) {
20
+ instance.$once('after-leave', afterLeaveCallback);
21
+ } else {
22
+ instance.$on('after-leave', afterLeaveCallback);
23
+ }
24
+ setTimeout(() => {
25
+ afterLeaveCallback();
26
+ }, speed + 100);
27
+ };
@@ -0,0 +1,90 @@
1
+ import Utils from './aria-utils';
2
+
3
+ /**
4
+ * @constructor
5
+ * @desc Dialog object providing modal focus management.
6
+ *
7
+ * Assumptions: The element serving as the dialog container is present in the
8
+ * DOM and hidden. The dialog container has role='dialog'.
9
+ *
10
+ * @param dialogId
11
+ * The ID of the element serving as the dialog container.
12
+ * @param focusAfterClosed
13
+ * Either the DOM node or the ID of the DOM node to focus when the
14
+ * dialog closes.
15
+ * @param focusFirst
16
+ * Optional parameter containing either the DOM node or the ID of the
17
+ * DOM node to focus when the dialog opens. If not specified, the
18
+ * first focusable element in the dialog will receive focus.
19
+ */
20
+ var aria = aria || {};
21
+ var tabEvent;
22
+
23
+ aria.Dialog = function(dialog, focusAfterClosed, focusFirst) {
24
+ this.dialogNode = dialog;
25
+ if (this.dialogNode === null || this.dialogNode.getAttribute('role') !== 'dialog') {
26
+ throw new Error('Dialog() requires a DOM element with ARIA role of dialog.');
27
+ }
28
+
29
+ if (typeof focusAfterClosed === 'string') {
30
+ this.focusAfterClosed = document.getElementById(focusAfterClosed);
31
+ } else if (typeof focusAfterClosed === 'object') {
32
+ this.focusAfterClosed = focusAfterClosed;
33
+ } else {
34
+ this.focusAfterClosed = null;
35
+ }
36
+
37
+ if (typeof focusFirst === 'string') {
38
+ this.focusFirst = document.getElementById(focusFirst);
39
+ } else if (typeof focusFirst === 'object') {
40
+ this.focusFirst = focusFirst;
41
+ } else {
42
+ this.focusFirst = null;
43
+ }
44
+
45
+ if (this.focusFirst) {
46
+ this.focusFirst.focus();
47
+ } else {
48
+ Utils.focusFirstDescendant(this.dialogNode);
49
+ }
50
+
51
+ this.lastFocus = document.activeElement;
52
+ tabEvent = (e) => {
53
+ this.trapFocus(e);
54
+ };
55
+ this.addListeners();
56
+ };
57
+
58
+ aria.Dialog.prototype.addListeners = function() {
59
+ document.addEventListener('focus', tabEvent, true);
60
+ };
61
+
62
+ aria.Dialog.prototype.removeListeners = function() {
63
+ document.removeEventListener('focus', tabEvent, true);
64
+ };
65
+
66
+ aria.Dialog.prototype.closeDialog = function() {
67
+ this.removeListeners();
68
+ if (this.focusAfterClosed) {
69
+ setTimeout(() => {
70
+ this.focusAfterClosed.focus();
71
+ });
72
+ }
73
+ };
74
+
75
+ aria.Dialog.prototype.trapFocus = function(event) {
76
+ if (Utils.IgnoreUtilFocusChanges) {
77
+ return;
78
+ }
79
+ if (this.dialogNode.contains(event.target)) {
80
+ this.lastFocus = event.target;
81
+ } else {
82
+ Utils.focusFirstDescendant(this.dialogNode);
83
+ if (this.lastFocus === document.activeElement) {
84
+ Utils.focusLastDescendant(this.dialogNode);
85
+ }
86
+ this.lastFocus = document.activeElement;
87
+ }
88
+ };
89
+
90
+ export default aria.Dialog;
@@ -0,0 +1,122 @@
1
+ var aria = aria || {};
2
+
3
+ aria.Utils = aria.Utils || {};
4
+
5
+ /**
6
+ * @desc Set focus on descendant nodes until the first focusable element is
7
+ * found.
8
+ * @param element
9
+ * DOM node for which to find the first focusable descendant.
10
+ * @returns
11
+ * true if a focusable element is found and focus is set.
12
+ */
13
+ aria.Utils.focusFirstDescendant = function(element) {
14
+ for (var i = 0; i < element.childNodes.length; i++) {
15
+ var child = element.childNodes[i];
16
+ if (aria.Utils.attemptFocus(child) || aria.Utils.focusFirstDescendant(child)) {
17
+ return true;
18
+ }
19
+ }
20
+ return false;
21
+ };
22
+
23
+ /**
24
+ * @desc Find the last descendant node that is focusable.
25
+ * @param element
26
+ * DOM node for which to find the last focusable descendant.
27
+ * @returns
28
+ * true if a focusable element is found and focus is set.
29
+ */
30
+
31
+ aria.Utils.focusLastDescendant = function(element) {
32
+ for (var i = element.childNodes.length - 1; i >= 0; i--) {
33
+ var child = element.childNodes[i];
34
+ if (aria.Utils.attemptFocus(child) || aria.Utils.focusLastDescendant(child)) {
35
+ return true;
36
+ }
37
+ }
38
+ return false;
39
+ };
40
+
41
+ /**
42
+ * @desc Set Attempt to set focus on the current node.
43
+ * @param element
44
+ * The node to attempt to focus on.
45
+ * @returns
46
+ * true if element is focused.
47
+ */
48
+ aria.Utils.attemptFocus = function(element) {
49
+ if (!aria.Utils.isFocusable(element)) {
50
+ return false;
51
+ }
52
+ aria.Utils.IgnoreUtilFocusChanges = true;
53
+ try {
54
+ element.focus();
55
+ } catch (e) {
56
+ }
57
+ aria.Utils.IgnoreUtilFocusChanges = false;
58
+ return (document.activeElement === element);
59
+ };
60
+
61
+ aria.Utils.isFocusable = function(element) {
62
+ if (element.tabIndex > 0 || (element.tabIndex === 0 && element.getAttribute('tabIndex') !== null)) {
63
+ return true;
64
+ }
65
+
66
+ if (element.disabled) {
67
+ return false;
68
+ }
69
+
70
+ switch (element.nodeName) {
71
+ case 'A':
72
+ return !!element.href && element.rel !== 'ignore';
73
+ case 'INPUT':
74
+ return element.type !== 'hidden' && element.type !== 'file';
75
+ case 'BUTTON':
76
+ case 'SELECT':
77
+ case 'TEXTAREA':
78
+ return true;
79
+ default:
80
+ return false;
81
+ }
82
+ };
83
+
84
+ /**
85
+ * 触发一个事件
86
+ * mouseenter, mouseleave, mouseover, keyup, change, click 等
87
+ * @param {Element} elm
88
+ * @param {String} name
89
+ * @param {*} opts
90
+ */
91
+ aria.Utils.triggerEvent = function(elm, name, ...opts) {
92
+ let eventName;
93
+
94
+ if (/^mouse|click/.test(name)) {
95
+ eventName = 'MouseEvents';
96
+ } else if (/^key/.test(name)) {
97
+ eventName = 'KeyboardEvent';
98
+ } else {
99
+ eventName = 'HTMLEvents';
100
+ }
101
+ const evt = document.createEvent(eventName);
102
+
103
+ evt.initEvent(name, ...opts);
104
+ elm.dispatchEvent
105
+ ? elm.dispatchEvent(evt)
106
+ : elm.fireEvent('on' + name, evt);
107
+
108
+ return elm;
109
+ };
110
+
111
+ aria.Utils.keys = {
112
+ tab: 9,
113
+ enter: 13,
114
+ space: 32,
115
+ left: 37,
116
+ up: 38,
117
+ right: 39,
118
+ down: 40,
119
+ esc: 27
120
+ };
121
+
122
+ export default aria.Utils;
@@ -0,0 +1,76 @@
1
+ import Vue from 'vue';
2
+ import { on } from './dom';
3
+
4
+ const nodeList = [];
5
+ const ctx = '@@clickoutsideContext';
6
+
7
+ let startClick;
8
+ let seed = 0;
9
+
10
+ !Vue.prototype.$isServer && on(document, 'mousedown', e => (startClick = e));
11
+
12
+ !Vue.prototype.$isServer && on(document, 'mouseup', e => {
13
+ nodeList.forEach(node => node[ctx].documentHandler(e, startClick));
14
+ });
15
+
16
+ function createDocumentHandler(el, binding, vnode) {
17
+ return function(mouseup = {}, mousedown = {}) {
18
+ if (!vnode ||
19
+ !vnode.context ||
20
+ !mouseup.target ||
21
+ !mousedown.target ||
22
+ el.contains(mouseup.target) ||
23
+ el.contains(mousedown.target) ||
24
+ el === mouseup.target ||
25
+ (vnode.context.popperElm &&
26
+ (vnode.context.popperElm.contains(mouseup.target) ||
27
+ vnode.context.popperElm.contains(mousedown.target)))) return;
28
+
29
+ if (binding.expression &&
30
+ el[ctx].methodName &&
31
+ vnode.context[el[ctx].methodName]) {
32
+ vnode.context[el[ctx].methodName]();
33
+ } else {
34
+ el[ctx].bindingFn && el[ctx].bindingFn();
35
+ }
36
+ };
37
+ }
38
+
39
+ /**
40
+ * v-clickoutside
41
+ * @desc 点击元素外面才会触发的事件
42
+ * @example
43
+ * ```vue
44
+ * <div v-element-clickoutside="handleClose">
45
+ * ```
46
+ */
47
+ export default {
48
+ bind(el, binding, vnode) {
49
+ nodeList.push(el);
50
+ const id = seed++;
51
+ el[ctx] = {
52
+ id,
53
+ documentHandler: createDocumentHandler(el, binding, vnode),
54
+ methodName: binding.expression,
55
+ bindingFn: binding.value
56
+ };
57
+ },
58
+
59
+ update(el, binding, vnode) {
60
+ el[ctx].documentHandler = createDocumentHandler(el, binding, vnode);
61
+ el[ctx].methodName = binding.expression;
62
+ el[ctx].bindingFn = binding.value;
63
+ },
64
+
65
+ unbind(el) {
66
+ let len = nodeList.length;
67
+
68
+ for (let i = 0; i < len; i++) {
69
+ if (nodeList[i][ctx].id === el[ctx].id) {
70
+ nodeList.splice(i, 1);
71
+ break;
72
+ }
73
+ }
74
+ delete el[ctx];
75
+ }
76
+ };