vuse-directive 1.0.0 → 1.0.1
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/README.md +36 -0
- package/dist/vue-directive.js +13 -11
- package/dist/vue-directive.umd.cjs +1 -1
- package/package.json +10 -3
- /package/{dist → types}/directives/DebounceClick.d.ts +0 -0
- /package/{dist → types}/directives/ThrottleClick.d.ts +0 -0
- /package/{dist → types}/index.d.ts +0 -0
- /package/{dist → types}/utils/index.d.ts +0 -0
package/README.md
CHANGED
|
@@ -110,6 +110,42 @@ app.directive('debounce-click', makeDebounceClick(3000))
|
|
|
110
110
|
|
|
111
111
|
---
|
|
112
112
|
|
|
113
|
+
## ⚠️ Important Notes
|
|
114
|
+
|
|
115
|
+
### Always pass a function, not a function call
|
|
116
|
+
|
|
117
|
+
Unlike `@click`, custom directives do **not** auto-wrap the binding value in a function. Writing `v-throttle-click="fn(arg)"` causes `fn(arg)` to execute **at render time**, not on click.
|
|
118
|
+
|
|
119
|
+
```vue
|
|
120
|
+
<!-- ❌ Wrong: fn(arg) is called on every render -->
|
|
121
|
+
<button v-throttle-click="handleClick(id)">Click</button>
|
|
122
|
+
|
|
123
|
+
<!-- ✅ Correct: wrap in an arrow function -->
|
|
124
|
+
<button v-throttle-click="() => handleClick(id)">Click</button>
|
|
125
|
+
|
|
126
|
+
<!-- ✅ Also fine: no arguments, pass the reference directly -->
|
|
127
|
+
<button v-throttle-click="handleClick">Click</button>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
This is especially easy to get wrong inside scoped slots where you need to pass slot data as an argument:
|
|
131
|
+
|
|
132
|
+
```vue
|
|
133
|
+
<!-- ❌ Wrong: deleteRow(scope.$index) fires on every row render -->
|
|
134
|
+
<template #default="scope">
|
|
135
|
+
<button v-throttle-click="deleteRow(scope.$index)">Delete</button>
|
|
136
|
+
</template>
|
|
137
|
+
|
|
138
|
+
<!-- ✅ Correct -->
|
|
139
|
+
<template #default="scope">
|
|
140
|
+
<button v-throttle-click="() => deleteRow(scope.$index)">Delete</button>
|
|
141
|
+
</template>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
> **Why does `@click="fn(arg)"` work then?**
|
|
145
|
+
> Vue's template compiler treats event listeners specially and automatically compiles them into `onClick: ($event) => fn(arg)`. Custom directives receive a plain evaluated expression, so no wrapping happens.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
113
149
|
## Issues
|
|
114
150
|
|
|
115
151
|
Found a bug or have a suggestion? Feel free to send an email to:
|
package/dist/vue-directive.js
CHANGED
|
@@ -20,22 +20,22 @@ const v = (r) => typeof Symbol == "function" ? Symbol(r) : `__${r}__`, d = v("de
|
|
|
20
20
|
i.modifiers
|
|
21
21
|
);
|
|
22
22
|
e._debounceHandler = f((l) => {
|
|
23
|
-
const { modifiers: o, value:
|
|
23
|
+
const { modifiers: o, value: c } = e._latestBinding;
|
|
24
24
|
if (o.once && e._hasCalledOnce)
|
|
25
25
|
return;
|
|
26
26
|
const u = typeof e._latestBinding.arg > "u" ? 300 : Number(e._latestBinding.arg);
|
|
27
27
|
e._lastEvent = l;
|
|
28
|
-
const
|
|
29
|
-
e._hasCalledOnce = !0,
|
|
28
|
+
const _ = (p) => {
|
|
29
|
+
e._hasCalledOnce = !0, c == null || c(p);
|
|
30
30
|
};
|
|
31
31
|
if (u === 0) {
|
|
32
|
-
|
|
32
|
+
_(l);
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
|
-
o.leading && !e._leadingFired ? (e._leadingFired = !0,
|
|
36
|
-
e._maxWaitTimer = null, e._debounceTimer && (clearTimeout(e._debounceTimer), e._debounceTimer = null), e._waiting && e._lastEvent && (e._waiting = !1,
|
|
35
|
+
o.leading && !e._leadingFired ? (e._leadingFired = !0, _(l)) : e._waiting = !0, e._debounceTimer && clearTimeout(e._debounceTimer), n > 0 && e._maxWaitTimer === null && (e._maxWaitTimer = setTimeout(() => {
|
|
36
|
+
e._maxWaitTimer = null, e._debounceTimer && (clearTimeout(e._debounceTimer), e._debounceTimer = null), e._waiting && e._lastEvent && (e._waiting = !1, _(e._lastEvent)), e._leadingFired = !1;
|
|
37
37
|
}, n)), e._debounceTimer = setTimeout(() => {
|
|
38
|
-
e._debounceTimer = null, e._maxWaitTimer && (clearTimeout(e._maxWaitTimer), e._maxWaitTimer = null), e._waiting && (e._waiting = !1,
|
|
38
|
+
e._debounceTimer = null, e._maxWaitTimer && (clearTimeout(e._maxWaitTimer), e._maxWaitTimer = null), e._waiting && (e._waiting = !1, _(l)), e._leadingFired = !1;
|
|
39
39
|
}, u);
|
|
40
40
|
}, a), i.modifiers.right && (e._eventName = "contextmenu"), e._listenerOptions = {
|
|
41
41
|
capture: i.modifiers.capture ?? !1,
|
|
@@ -100,10 +100,10 @@ const v = (r) => typeof Symbol == "function" ? Symbol(r) : `__${r}__`, d = v("de
|
|
|
100
100
|
e.trailing && (t._trailingEvent = i);
|
|
101
101
|
return;
|
|
102
102
|
}
|
|
103
|
-
const o = (
|
|
104
|
-
t._hasCalledOnce = !0, t._trailingEvent = null, e.async ? (t._asyncPending = !0, Promise.resolve(a == null ? void 0 : a(
|
|
103
|
+
const o = (c) => {
|
|
104
|
+
t._hasCalledOnce = !0, t._trailingEvent = null, e.async ? (t._asyncPending = !0, Promise.resolve(a == null ? void 0 : a(c)).finally(() => {
|
|
105
105
|
t._asyncPending = !1, !t._unmounted && e.trailing && t._trailingEvent && t._throttleHandler(t._trailingEvent);
|
|
106
|
-
})) : a == null || a(
|
|
106
|
+
})) : a == null || a(c);
|
|
107
107
|
};
|
|
108
108
|
if (l === 0) {
|
|
109
109
|
o(i);
|
|
@@ -122,7 +122,9 @@ const v = (r) => typeof Symbol == "function" ? Symbol(r) : `__${r}__`, d = v("de
|
|
|
122
122
|
);
|
|
123
123
|
},
|
|
124
124
|
updated(r, n) {
|
|
125
|
-
const t = r[m]
|
|
125
|
+
const t = r[m];
|
|
126
|
+
console.log("[lwb]", t);
|
|
127
|
+
const s = n.modifiers.capture ?? !1, i = n.modifiers.passive ?? !1, e = t._listenerOptions;
|
|
126
128
|
(s !== e.capture || i !== e.passive) && (r.removeEventListener(
|
|
127
129
|
t._eventName,
|
|
128
130
|
t._throttleHandler,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(o,d){typeof exports=="object"&&typeof module<"u"?d(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],d):(o=typeof globalThis<"u"?globalThis:o||self,d(o.VueDirective={},o.Vue))})(this,function(o,d){"use strict";const v=r=>typeof Symbol=="function"?Symbol(r):`__${r}__`,u=v("debounceClick"),p=r=>{const n=r;return{mounted(s,i){s[u]={_latestBinding:i,_debounceTimer:null,_maxWaitTimer:null,_hasCalledOnce:!1,_leadingFired:!1,_waiting:!1,_lastEvent:null,_eventName:"click",_listenerOptions:{},_debounceHandler:()=>{}};const e=s[u],
|
|
1
|
+
(function(o,d){typeof exports=="object"&&typeof module<"u"?d(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],d):(o=typeof globalThis<"u"?globalThis:o||self,d(o.VueDirective={},o.Vue))})(this,function(o,d){"use strict";const v=r=>typeof Symbol=="function"?Symbol(r):`__${r}__`,u=v("debounceClick"),p=r=>{const n=r;return{mounted(s,i){s[u]={_latestBinding:i,_debounceTimer:null,_maxWaitTimer:null,_hasCalledOnce:!1,_leadingFired:!1,_waiting:!1,_lastEvent:null,_eventName:"click",_listenerOptions:{},_debounceHandler:()=>{}};const e=s[u],l=Object.getOwnPropertyNames(i.modifiers);e._debounceHandler=d.withModifiers(a=>{const{modifiers:c,value:_}=e._latestBinding;if(c.once&&e._hasCalledOnce)return;const h=typeof e._latestBinding.arg>"u"?300:Number(e._latestBinding.arg);e._lastEvent=a;const f=y=>{e._hasCalledOnce=!0,_==null||_(y)};if(h===0){f(a);return}c.leading&&!e._leadingFired?(e._leadingFired=!0,f(a)):e._waiting=!0,e._debounceTimer&&clearTimeout(e._debounceTimer),n>0&&e._maxWaitTimer===null&&(e._maxWaitTimer=setTimeout(()=>{e._maxWaitTimer=null,e._debounceTimer&&(clearTimeout(e._debounceTimer),e._debounceTimer=null),e._waiting&&e._lastEvent&&(e._waiting=!1,f(e._lastEvent)),e._leadingFired=!1},n)),e._debounceTimer=setTimeout(()=>{e._debounceTimer=null,e._maxWaitTimer&&(clearTimeout(e._maxWaitTimer),e._maxWaitTimer=null),e._waiting&&(e._waiting=!1,f(a)),e._leadingFired=!1},h)},l),i.modifiers.right&&(e._eventName="contextmenu"),e._listenerOptions={capture:i.modifiers.capture??!1,passive:i.modifiers.passive??!1},s.addEventListener(e._eventName,e._debounceHandler,e._listenerOptions)},updated(s,i){const e=s[u],l=i.modifiers.capture??!1,a=i.modifiers.passive??!1,c=e._listenerOptions;(l!==c.capture||a!==c.passive)&&(s.removeEventListener(e._eventName,e._debounceHandler,c),e._listenerOptions={capture:l,passive:a},s.addEventListener(e._eventName,e._debounceHandler,e._listenerOptions)),e._latestBinding=i},unmounted(s){const i=s[u];s.removeEventListener(i._eventName,i._debounceHandler,i._listenerOptions),i._debounceTimer&&clearTimeout(i._debounceTimer),i._maxWaitTimer&&clearTimeout(i._maxWaitTimer)}}},g=p(-1),m=v("throttleClick"),T={mounted(r,n){r[m]={_latestBinding:n,_throttleTimer:null,_hasCalledOnce:!1,_trailingEvent:null,_asyncPending:!1,_unmounted:!1,_eventName:"click",_listenerOptions:{},_throttleHandler:()=>{}};const t=r[m],s=Object.getOwnPropertyNames(n.modifiers);t._throttleHandler=d.withModifiers(i=>{const{modifiers:e,value:l}=t._latestBinding;if(e.once&&t._hasCalledOnce)return;if(e.async&&t._asyncPending){e.trailing&&(t._trailingEvent=i);return}const a=typeof t._latestBinding.arg>"u"?300:Number(t._latestBinding.arg);if(a>0&&t._throttleTimer){e.trailing&&(t._trailingEvent=i);return}const c=_=>{t._hasCalledOnce=!0,t._trailingEvent=null,e.async?(t._asyncPending=!0,Promise.resolve(l==null?void 0:l(_)).finally(()=>{t._asyncPending=!1,!t._unmounted&&e.trailing&&t._trailingEvent&&t._throttleHandler(t._trailingEvent)})):l==null||l(_)};if(a===0){c(i);return}c(i),t._throttleTimer=setTimeout(()=>{t._throttleTimer=null,!e.async&&e.trailing&&t._trailingEvent&&(t._throttleHandler(t._trailingEvent),t._trailingEvent=null)},a)},s),t._eventName=n.modifiers.right?"contextmenu":"click",t._listenerOptions={capture:n.modifiers.capture??!1,passive:n.modifiers.passive??!1},r.addEventListener(t._eventName,t._throttleHandler,t._listenerOptions)},updated(r,n){const t=r[m];console.log("[lwb]",t);const s=n.modifiers.capture??!1,i=n.modifiers.passive??!1,e=t._listenerOptions;(s!==e.capture||i!==e.passive)&&(r.removeEventListener(t._eventName,t._throttleHandler,e),t._listenerOptions={capture:s,passive:i},r.addEventListener(t._eventName,t._throttleHandler,t._listenerOptions)),t._latestBinding=n},unmounted(r){const n=r[m];r.removeEventListener(n._eventName,n._throttleHandler,n._listenerOptions),n._throttleTimer&&clearTimeout(n._throttleTimer),n._unmounted=!0,n._trailingEvent=null}},O={install:r=>{r.directive("throttle-click",T),r.directive("debounce-click",g)}};o.debounceClick=g,o.default=O,o.makeDebounceClick=p,o.throttleClick=T,Object.defineProperties(o,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/package.json
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vuse-directive",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Vue 3 directives collection",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/vue-directive.umd.cjs",
|
|
7
7
|
"module": "./dist/vue-directive.js",
|
|
8
|
-
"types": "./
|
|
8
|
+
"types": "./types/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
11
|
"import": "./dist/vue-directive.js",
|
|
12
12
|
"require": "./dist/vue-directive.umd.cjs",
|
|
13
|
-
"types": "./
|
|
13
|
+
"types": "./types/index.d.ts"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
17
|
"dist",
|
|
18
|
+
"types",
|
|
18
19
|
"docs"
|
|
19
20
|
],
|
|
20
21
|
"scripts": {
|
|
@@ -36,6 +37,7 @@
|
|
|
36
37
|
"@types/node": "^25.3.0",
|
|
37
38
|
"@vitejs/plugin-vue": "^5.0.0",
|
|
38
39
|
"@vue/test-utils": "^2.4.6",
|
|
40
|
+
"cz-conventional-changelog": "^3.3.0",
|
|
39
41
|
"element-plus": "^2.13.3",
|
|
40
42
|
"husky": "^9.0.0",
|
|
41
43
|
"jest": "^30.2.0",
|
|
@@ -54,6 +56,11 @@
|
|
|
54
56
|
"directive",
|
|
55
57
|
"directives"
|
|
56
58
|
],
|
|
59
|
+
"config": {
|
|
60
|
+
"commitizen": {
|
|
61
|
+
"path": "./node_modules/cz-conventional-changelog"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
57
64
|
"sideEffects": false,
|
|
58
65
|
"author": "Stafan Hulk",
|
|
59
66
|
"license": "MIT",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|