Skip to content

Commit cca69b8

Browse files
committed
feat: v-clicks
1 parent d11319b commit cca69b8

File tree

6 files changed

+86
-30
lines changed

6 files changed

+86
-30
lines changed

slides.md

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ Pattens and tips for writing good composable logic in Vue
1010
Anthony Fu
1111
</div>
1212

13+
<div class="abs-bl m-14 text-sm opacity-50">
14+
Apr. 28th, 2021.
15+
</div>
16+
1317
---
1418
layout: cover
1519
---
@@ -22,7 +26,7 @@ Creator of VueUse, i18n Ally and Type Challenges.<br>
2226
A fanatical full-time open sourceror.<br>
2327
</div>
2428

25-
<div class="my-10 grid grid-cols-[40px,1fr] w-min gap-y-4 all-child:block all-child:my-auto">
29+
<div v-click class="my-10 grid grid-cols-[40px,1fr] w-min gap-y-4 all-child:block all-child:my-auto">
2630
<ri-github-line class="opacity-50"/>
2731
<div><a href="https://github.com/antfu" target="_blank">antfu</a></div>
2832
<ri-twitter-line class="opacity-50"/>
@@ -103,6 +107,8 @@ foo = 1
103107
bar = 1 // ts-error
104108
```
105109

110+
<div v-click>
111+
106112
### Pros
107113

108114
- More explicit, with type checking
@@ -112,6 +118,8 @@ bar = 1 // ts-error
112118

113119
- `.value`
114120

121+
</div>
122+
115123
</div><div>
116124

117125
# Reactive
@@ -126,6 +134,8 @@ foo.prop = 1
126134
bar.prop = 1
127135
```
128136

137+
<div v-click>
138+
129139
### Pros
130140

131141
- Auto unwrapping (a.k.a `.value` free)
@@ -136,6 +146,7 @@ bar.prop = 1
136146
- Destructure loses reactivity
137147
- Need to use callback for `watch`
138148

149+
</div>
139150
</div></div>
140151

141152
------
@@ -146,6 +157,8 @@ Get rid of `.value` for most of the time.
146157

147158
<div class="grid grid-cols-2 gap-x-4">
148159

160+
<v-clicks :every='2'>
161+
149162
- `watch` accepts ref as the watch target, and returns the unwrapped value in the callback
150163

151164
```ts
@@ -179,6 +192,8 @@ data.foo // 'bar'
179192

180193
</div>
181194

195+
</v-clicks>
196+
182197
</div>
183198

184199
------
@@ -252,6 +267,8 @@ layout: center
252267

253268
# Think as "Connections"
254269

270+
The `setup()` only runs **once** on component initialization, to construct the relations between your state and logic.
271+
255272
- Input -> Output
256273
- Spreadsheet formuala
257274

@@ -275,7 +292,7 @@ layout: center
275292

276293
### Usage
277294

278-
<v-click>
295+
<v-clicks :every='3'>
279296

280297
<div class="my-auto leading-6 text-base opacity-75">
281298
Plain function
@@ -289,7 +306,10 @@ function add(a: number, b: number) {
289306
```
290307

291308
```ts
292-
add(1, 2) // 3
309+
let a = 1
310+
let b = 2
311+
312+
let c = add(a, b) // 3
293313
```
294314

295315
<div class="my-auto leading-6 text-base opacity-75">
@@ -331,7 +351,7 @@ const c = add(a, 5)
331351
c.value // 6
332352
```
333353

334-
</v-click>
354+
</v-clicks>
335355

336356
</div>
337357

@@ -376,7 +396,7 @@ name.value = 'Hi' // Hi - World
376396

377397
</div></div>
378398

379-
<div class="abs-b mx-14 my-12">
399+
<div v-click class="abs-b mx-14 my-12">
380400
<VueUse name="useTitle"/>
381401
</div>
382402

@@ -390,9 +410,27 @@ A custom type helper
390410
type MaybeRef<T> = Ref<T> | T
391411
```
392412
393-
<br>
413+
<v-click>
414+
415+
In VueUse, we use this helper heavily to support optional reactive arguments
416+
417+
```ts
418+
export function useTimeAgo(
419+
time: MaybeRef<Date | number | string>,
420+
options: TimeAgoOptions = {},
421+
) {
422+
return computed(() => someFormating(unref(time)))
423+
}
424+
```
425+
426+
```ts
427+
useTimeAgo(1618478282830) // 5 mins ago
394428

395-
In VueUse, we use this helper heavily to support
429+
const time = ref('2021-04-28')
430+
const timeString = useTimeAgo(time) // Today
431+
```
432+
433+
</v-click>
396434

397435
------
398436

src/components/VClick.ts

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,8 @@
1-
import { defineComponent, resolveDirective, VNode, withDirectives } from 'vue'
1+
import { createVNode, defineComponent } from 'vue'
2+
import VClicks from './VClicks'
23

34
export default defineComponent({
45
render() {
5-
const click = resolveDirective('click')!
6-
7-
function applyDirective(node: VNode) {
8-
// @ts-expect-error
9-
if (node.dirs?.find(i => i.dir.name && ['v-click', 'v-after'].includes(i.dir.name)))
10-
return node
11-
return withDirectives(node, [[click]])
12-
}
13-
14-
const defaults = this.$slots.default?.()
15-
16-
if (!defaults)
17-
return
18-
19-
if (Array.isArray(defaults))
20-
return defaults.map(i => applyDirective(i))
21-
22-
return applyDirective(defaults)
6+
return createVNode(VClicks, { every: 99999 }, { default: this.$slots.default })
237
},
248
})

src/components/VClicks.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { defineComponent, Directive, resolveDirective, VNode, withDirectives } from 'vue'
2+
3+
export default defineComponent({
4+
props: {
5+
every: {
6+
default: 1,
7+
},
8+
},
9+
render() {
10+
const click = resolveDirective('click')!
11+
const after = resolveDirective('after')!
12+
13+
function applyDirective(node: VNode, directive: Directive) {
14+
// @ts-expect-error
15+
if (node.dirs?.find(i => i.dir.name && ['v-click', 'v-after'].includes(i.dir.name)))
16+
return node
17+
return withDirectives(node, [[directive]])
18+
}
19+
20+
const defaults = this.$slots.default?.()
21+
22+
if (!defaults)
23+
return
24+
25+
if (Array.isArray(defaults))
26+
return defaults.map((i, idx) => applyDirective(i, idx % this.every === 0 ? click : after))
27+
28+
return applyDirective(defaults, click)
29+
},
30+
})

src/layouts/default.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,9 @@
6767
td, th {
6868
@apply p-2 py-3;
6969
}
70+
71+
b, strong {
72+
@apply font-600;
73+
}
7074
}
7175
</style>

src/modules/directives.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export const install: UserModule = ({ app }) => {
2323
clickCurrent,
2424
() => {
2525
const show = clickCurrent.value > prev
26-
el.classList.toggle('hidden', !show)
26+
el.classList.toggle('!opacity-0', !show)
2727
},
2828
{ immediate: true },
2929
)
@@ -43,8 +43,8 @@ export const install: UserModule = ({ app }) => {
4343
watch(
4444
clickCurrent,
4545
() => {
46-
const show = clickCurrent.value > prev
47-
el.classList.toggle('hidden', !show)
46+
const show = clickCurrent.value >= prev
47+
el.classList.toggle('!opacity-0', !show)
4848
},
4949
{ immediate: true },
5050
)

windi.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default defineConfig({
77
'slides.md',
88
],
99
},
10-
safelist: 'hidden',
10+
safelist: '!opacity-0',
1111
darkMode: 'class',
1212
preflight: {
1313
includeAll: true,

0 commit comments

Comments
 (0)