vue-intercept-plugin 1.0.1 → 1.1.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.
package/dist/index.d.ts CHANGED
@@ -1,24 +1,32 @@
1
1
  /**
2
- * 解析指令值,生成实际的事件处理函数
3
- * 支持两种格式:
4
- * 1. 函数:v-intercept="handleDelete"
5
- * 2. 数组:v-intercept="[handleDelete, 1001]"
2
+ * Resolves the directive value into an actual event listener.
3
+ * Supports two formats:
4
+ * 1. Function: v-intercept="handleDelete"
5
+ * 2. Array: v-intercept="[handleDelete, 1001]"
6
6
  */
7
7
  declare function resolveHandler(value: unknown): EventListener | null;
8
8
  /**
9
- * 在元素上绑定事件
9
+ * Binds an event listener on the element.
10
+ * Removes the old listener before binding a new one to prevent duplicates.
10
11
  */
11
- declare function bindHandler(el: HTMLElement, eventType: string, handler: EventListener): void;
12
+ declare function bindHandler(el: HTMLElement, eventType: string, handler: EventListener, options?: AddEventListenerOptions): void;
12
13
  /**
13
- * 移除元素上的事件监听
14
+ * Removes an event listener from the element.
14
15
  */
15
16
  declare function unbindHandler(el: HTMLElement, eventType: string): void;
16
17
  /**
17
- * Vue 事件拦截插件
18
+ * Vue event interception plugin.
18
19
  *
19
- * 提供 v-intercept 自定义指令,用于拦截事件。
20
- * 默认拦截 click 事件,可通过指令参数指定其他事件类型。
21
- * 开发者在使用时,在函数内部自行判断权限并决定是否放行。
20
+ * Provides the v-intercept custom directive for intercepting DOM events.
21
+ * Defaults to click; specify other events via directive argument.
22
+ * Supports modifiers: .capture, .once, .passive.
23
+ *
24
+ * @example
25
+ * v-intercept="handleClick" // click (default)
26
+ * v-intercept:change="handleChange" // change event
27
+ * v-intercept:click.capture="handleClick" // click with capture
28
+ * v-intercept:scroll.passive="handleScroll" // scroll with passive
29
+ * v-intercept:click.once="handleOnce" // click with once
22
30
  */
23
31
  declare const VueInterceptPlugin: {
24
32
  install(app: any): void;
@@ -3,19 +3,23 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  /**
6
- * WeakMap 存储元素 事件类型监听函数的映射
7
- * 避免在 DOM 元素上挂载自定义属性(el._intcpt_xxx
6
+ * Stores elementevent type listener mapping via WeakMap.
7
+ * Avoids attaching custom properties (el._intcpt_xxx) to DOM elements.
8
8
  */
9
9
  const handlerMap = new WeakMap();
10
10
  /**
11
- * 获取元素上指定事件类型的监听函数
11
+ * Stores element → event type → options mapping via WeakMap.
12
+ */
13
+ const optionsMap = new WeakMap();
14
+ /**
15
+ * Gets the listener for a specific event type on an element.
12
16
  */
13
17
  function getHandler(el, eventType) {
14
18
  var _a;
15
19
  return (_a = handlerMap.get(el)) === null || _a === void 0 ? void 0 : _a.get(eventType);
16
20
  }
17
21
  /**
18
- * 设置元素上指定事件类型的监听函数
22
+ * Sets the listener for a specific event type on an element.
19
23
  */
20
24
  function setHandler(el, eventType, handler) {
21
25
  let typeMap = handlerMap.get(el);
@@ -26,20 +30,53 @@ function setHandler(el, eventType, handler) {
26
30
  typeMap.set(eventType, handler);
27
31
  }
28
32
  /**
29
- * 删除元素上指定事件类型的监听函数
33
+ * Deletes the listener for a specific event type on an element.
34
+ * Cleans up the WeakMap entry when no types remain.
30
35
  */
31
36
  function deleteHandler(el, eventType) {
32
- var _a, _b;
33
- (_a = handlerMap.get(el)) === null || _a === void 0 ? void 0 : _a.delete(eventType);
34
- if (((_b = handlerMap.get(el)) === null || _b === void 0 ? void 0 : _b.size) === 0) {
37
+ const typeMap = handlerMap.get(el);
38
+ if (!typeMap)
39
+ return;
40
+ typeMap.delete(eventType);
41
+ if (typeMap.size === 0) {
35
42
  handlerMap.delete(el);
36
43
  }
37
44
  }
38
45
  /**
39
- * 解析指令值,生成实际的事件处理函数
40
- * 支持两种格式:
41
- * 1. 函数:v-intercept="handleDelete"
42
- * 2. 数组:v-intercept="[handleDelete, 1001]"
46
+ * Gets the event options for a specific event type on an element.
47
+ */
48
+ function getOptions(el, eventType) {
49
+ var _a;
50
+ return (_a = optionsMap.get(el)) === null || _a === void 0 ? void 0 : _a.get(eventType);
51
+ }
52
+ /**
53
+ * Sets the event options for a specific event type on an element.
54
+ */
55
+ function setOptions(el, eventType, options) {
56
+ let typeMap = optionsMap.get(el);
57
+ if (!typeMap) {
58
+ typeMap = new Map();
59
+ optionsMap.set(el, typeMap);
60
+ }
61
+ typeMap.set(eventType, options);
62
+ }
63
+ /**
64
+ * Deletes the event options for a specific event type on an element.
65
+ */
66
+ function deleteOptions(el, eventType) {
67
+ const typeMap = optionsMap.get(el);
68
+ if (!typeMap)
69
+ return;
70
+ typeMap.delete(eventType);
71
+ if (typeMap.size === 0) {
72
+ optionsMap.delete(el);
73
+ }
74
+ }
75
+ /**
76
+ * Resolves the directive value into an actual event listener.
77
+ * Supports two formats:
78
+ * 1. Function: v-intercept="handleDelete"
79
+ * 2. Array: v-intercept="[handleDelete, 1001]"
43
80
  */
44
81
  function resolveHandler(value) {
45
82
  if (typeof value === 'function') {
@@ -48,45 +85,59 @@ function resolveHandler(value) {
48
85
  if (Array.isArray(value)) {
49
86
  const [fn, ...args] = value;
50
87
  if (typeof fn !== 'function') {
51
- console.warn('[vue-intercept-plugin] 数组第一项必须是一个函数');
88
+ console.warn('[vue-intercept-plugin] The first item in the array must be a function');
52
89
  return null;
53
90
  }
54
91
  return (event) => { fn(...args, event); };
55
92
  }
56
- console.warn('[vue-intercept-plugin] v-intercept 的值必须是函数或 [函数, ...参数] 数组');
93
+ console.warn('[vue-intercept-plugin] v-intercept value must be a function or [function, ...args] array');
57
94
  return null;
58
95
  }
59
96
  /**
60
- * 在元素上绑定事件
97
+ * Binds an event listener on the element.
98
+ * Removes the old listener before binding a new one to prevent duplicates.
61
99
  */
62
- function bindHandler(el, eventType, handler) {
100
+ function bindHandler(el, eventType, handler, options) {
63
101
  const oldHandler = getHandler(el, eventType);
102
+ const oldOptions = getOptions(el, eventType);
64
103
  if (oldHandler) {
65
- el.removeEventListener(eventType, oldHandler);
104
+ el.removeEventListener(eventType, oldHandler, oldOptions);
66
105
  }
67
- el.addEventListener(eventType, handler);
106
+ el.addEventListener(eventType, handler, options);
68
107
  setHandler(el, eventType, handler);
108
+ if (options) {
109
+ setOptions(el, eventType, options);
110
+ }
69
111
  }
70
112
  /**
71
- * 移除元素上的事件监听
113
+ * Removes an event listener from the element.
72
114
  */
73
115
  function unbindHandler(el, eventType) {
74
116
  const handler = getHandler(el, eventType);
117
+ const options = getOptions(el, eventType);
75
118
  if (handler) {
76
- el.removeEventListener(eventType, handler);
119
+ el.removeEventListener(eventType, handler, options);
77
120
  deleteHandler(el, eventType);
121
+ deleteOptions(el, eventType);
78
122
  }
79
123
  }
80
124
  /**
81
- * Vue 事件拦截插件
125
+ * Vue event interception plugin.
126
+ *
127
+ * Provides the v-intercept custom directive for intercepting DOM events.
128
+ * Defaults to click; specify other events via directive argument.
129
+ * Supports modifiers: .capture, .once, .passive.
82
130
  *
83
- * 提供 v-intercept 自定义指令,用于拦截事件。
84
- * 默认拦截 click 事件,可通过指令参数指定其他事件类型。
85
- * 开发者在使用时,在函数内部自行判断权限并决定是否放行。
131
+ * @example
132
+ * v-intercept="handleClick" // click (default)
133
+ * v-intercept:change="handleChange" // change event
134
+ * v-intercept:click.capture="handleClick" // click with capture
135
+ * v-intercept:scroll.passive="handleScroll" // scroll with passive
136
+ * v-intercept:click.once="handleOnce" // click with once
86
137
  */
87
138
  const VueInterceptPlugin = {
88
139
  install(app) {
89
- // SSR 安全:非浏览器环境直接跳过
140
+ // SSR safety: skip in non-browser environments
90
141
  if (typeof window === 'undefined') {
91
142
  return;
92
143
  }
@@ -96,7 +147,16 @@ const VueInterceptPlugin = {
96
147
  if (!handler)
97
148
  return;
98
149
  const eventType = binding.arg || 'click';
99
- bindHandler(el, eventType, handler);
150
+ const options = {};
151
+ if (binding.modifiers) {
152
+ if (binding.modifiers.capture)
153
+ options.capture = true;
154
+ if (binding.modifiers.once)
155
+ options.once = true;
156
+ if (binding.modifiers.passive)
157
+ options.passive = true;
158
+ }
159
+ bindHandler(el, eventType, handler, Object.keys(options).length > 0 ? options : undefined);
100
160
  }
101
161
  function unbind(el, binding) {
102
162
  const eventType = binding.arg || 'click';
@@ -1,17 +1,21 @@
1
1
  /**
2
- * WeakMap 存储元素 事件类型监听函数的映射
3
- * 避免在 DOM 元素上挂载自定义属性(el._intcpt_xxx
2
+ * Stores elementevent type listener mapping via WeakMap.
3
+ * Avoids attaching custom properties (el._intcpt_xxx) to DOM elements.
4
4
  */
5
5
  const handlerMap = new WeakMap();
6
6
  /**
7
- * 获取元素上指定事件类型的监听函数
7
+ * Stores element → event type → options mapping via WeakMap.
8
+ */
9
+ const optionsMap = new WeakMap();
10
+ /**
11
+ * Gets the listener for a specific event type on an element.
8
12
  */
9
13
  function getHandler(el, eventType) {
10
14
  var _a;
11
15
  return (_a = handlerMap.get(el)) === null || _a === void 0 ? void 0 : _a.get(eventType);
12
16
  }
13
17
  /**
14
- * 设置元素上指定事件类型的监听函数
18
+ * Sets the listener for a specific event type on an element.
15
19
  */
16
20
  function setHandler(el, eventType, handler) {
17
21
  let typeMap = handlerMap.get(el);
@@ -22,20 +26,53 @@ function setHandler(el, eventType, handler) {
22
26
  typeMap.set(eventType, handler);
23
27
  }
24
28
  /**
25
- * 删除元素上指定事件类型的监听函数
29
+ * Deletes the listener for a specific event type on an element.
30
+ * Cleans up the WeakMap entry when no types remain.
26
31
  */
27
32
  function deleteHandler(el, eventType) {
28
- var _a, _b;
29
- (_a = handlerMap.get(el)) === null || _a === void 0 ? void 0 : _a.delete(eventType);
30
- if (((_b = handlerMap.get(el)) === null || _b === void 0 ? void 0 : _b.size) === 0) {
33
+ const typeMap = handlerMap.get(el);
34
+ if (!typeMap)
35
+ return;
36
+ typeMap.delete(eventType);
37
+ if (typeMap.size === 0) {
31
38
  handlerMap.delete(el);
32
39
  }
33
40
  }
34
41
  /**
35
- * 解析指令值,生成实际的事件处理函数
36
- * 支持两种格式:
37
- * 1. 函数:v-intercept="handleDelete"
38
- * 2. 数组:v-intercept="[handleDelete, 1001]"
42
+ * Gets the event options for a specific event type on an element.
43
+ */
44
+ function getOptions(el, eventType) {
45
+ var _a;
46
+ return (_a = optionsMap.get(el)) === null || _a === void 0 ? void 0 : _a.get(eventType);
47
+ }
48
+ /**
49
+ * Sets the event options for a specific event type on an element.
50
+ */
51
+ function setOptions(el, eventType, options) {
52
+ let typeMap = optionsMap.get(el);
53
+ if (!typeMap) {
54
+ typeMap = new Map();
55
+ optionsMap.set(el, typeMap);
56
+ }
57
+ typeMap.set(eventType, options);
58
+ }
59
+ /**
60
+ * Deletes the event options for a specific event type on an element.
61
+ */
62
+ function deleteOptions(el, eventType) {
63
+ const typeMap = optionsMap.get(el);
64
+ if (!typeMap)
65
+ return;
66
+ typeMap.delete(eventType);
67
+ if (typeMap.size === 0) {
68
+ optionsMap.delete(el);
69
+ }
70
+ }
71
+ /**
72
+ * Resolves the directive value into an actual event listener.
73
+ * Supports two formats:
74
+ * 1. Function: v-intercept="handleDelete"
75
+ * 2. Array: v-intercept="[handleDelete, 1001]"
39
76
  */
40
77
  function resolveHandler(value) {
41
78
  if (typeof value === 'function') {
@@ -44,45 +81,59 @@ function resolveHandler(value) {
44
81
  if (Array.isArray(value)) {
45
82
  const [fn, ...args] = value;
46
83
  if (typeof fn !== 'function') {
47
- console.warn('[vue-intercept-plugin] 数组第一项必须是一个函数');
84
+ console.warn('[vue-intercept-plugin] The first item in the array must be a function');
48
85
  return null;
49
86
  }
50
87
  return (event) => { fn(...args, event); };
51
88
  }
52
- console.warn('[vue-intercept-plugin] v-intercept 的值必须是函数或 [函数, ...参数] 数组');
89
+ console.warn('[vue-intercept-plugin] v-intercept value must be a function or [function, ...args] array');
53
90
  return null;
54
91
  }
55
92
  /**
56
- * 在元素上绑定事件
93
+ * Binds an event listener on the element.
94
+ * Removes the old listener before binding a new one to prevent duplicates.
57
95
  */
58
- function bindHandler(el, eventType, handler) {
96
+ function bindHandler(el, eventType, handler, options) {
59
97
  const oldHandler = getHandler(el, eventType);
98
+ const oldOptions = getOptions(el, eventType);
60
99
  if (oldHandler) {
61
- el.removeEventListener(eventType, oldHandler);
100
+ el.removeEventListener(eventType, oldHandler, oldOptions);
62
101
  }
63
- el.addEventListener(eventType, handler);
102
+ el.addEventListener(eventType, handler, options);
64
103
  setHandler(el, eventType, handler);
104
+ if (options) {
105
+ setOptions(el, eventType, options);
106
+ }
65
107
  }
66
108
  /**
67
- * 移除元素上的事件监听
109
+ * Removes an event listener from the element.
68
110
  */
69
111
  function unbindHandler(el, eventType) {
70
112
  const handler = getHandler(el, eventType);
113
+ const options = getOptions(el, eventType);
71
114
  if (handler) {
72
- el.removeEventListener(eventType, handler);
115
+ el.removeEventListener(eventType, handler, options);
73
116
  deleteHandler(el, eventType);
117
+ deleteOptions(el, eventType);
74
118
  }
75
119
  }
76
120
  /**
77
- * Vue 事件拦截插件
121
+ * Vue event interception plugin.
122
+ *
123
+ * Provides the v-intercept custom directive for intercepting DOM events.
124
+ * Defaults to click; specify other events via directive argument.
125
+ * Supports modifiers: .capture, .once, .passive.
78
126
  *
79
- * 提供 v-intercept 自定义指令,用于拦截事件。
80
- * 默认拦截 click 事件,可通过指令参数指定其他事件类型。
81
- * 开发者在使用时,在函数内部自行判断权限并决定是否放行。
127
+ * @example
128
+ * v-intercept="handleClick" // click (default)
129
+ * v-intercept:change="handleChange" // change event
130
+ * v-intercept:click.capture="handleClick" // click with capture
131
+ * v-intercept:scroll.passive="handleScroll" // scroll with passive
132
+ * v-intercept:click.once="handleOnce" // click with once
82
133
  */
83
134
  const VueInterceptPlugin = {
84
135
  install(app) {
85
- // SSR 安全:非浏览器环境直接跳过
136
+ // SSR safety: skip in non-browser environments
86
137
  if (typeof window === 'undefined') {
87
138
  return;
88
139
  }
@@ -92,7 +143,16 @@ const VueInterceptPlugin = {
92
143
  if (!handler)
93
144
  return;
94
145
  const eventType = binding.arg || 'click';
95
- bindHandler(el, eventType, handler);
146
+ const options = {};
147
+ if (binding.modifiers) {
148
+ if (binding.modifiers.capture)
149
+ options.capture = true;
150
+ if (binding.modifiers.once)
151
+ options.once = true;
152
+ if (binding.modifiers.passive)
153
+ options.passive = true;
154
+ }
155
+ bindHandler(el, eventType, handler, Object.keys(options).length > 0 ? options : undefined);
96
156
  }
97
157
  function unbind(el, binding) {
98
158
  const eventType = binding.arg || 'click';
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "vue-intercept-plugin",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "A lightweight Vue plugin providing v-intercept custom directive — intercept DOM events with a single line of code, supports any event type, compatible with Vue 2 & Vue 3.",
5
5
  "main": "dist/vue-intercept-plugin.cjs.js",
6
6
  "module": "dist/vue-intercept-plugin.esm.js",
7
+ "types": "dist/index.d.ts",
7
8
  "files": [
8
9
  "dist"
9
10
  ],