Skip to content
This repository was archived by the owner on Jul 19, 2025. It is now read-only.

Commit e1bedb8

Browse files
authored
refactor!: drop custom directives (#274)
1 parent 6791c88 commit e1bedb8

16 files changed

+53
-484
lines changed

benchmark/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"paths": {
2020
"vue": ["../packages/vue/src"],
2121
"@vue/vapor": ["../packages/vue-vapor/src"],
22+
"vue/vapor": ["../packages/vue-vapor/src"],
2223
"@vue/*": ["../packages/*/src"]
2324
}
2425
},

packages/runtime-vapor/__tests__/apiCreateVaporApp.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ describe('api: createVaporApp', () => {
153153
expect(host.innerHTML).toBe(`foobar!barbaz!`)
154154
})
155155

156-
test('directive', () => {
156+
test.todo('directive', () => {
157157
const spy1 = vi.fn()
158158
const spy2 = vi.fn()
159159

packages/runtime-vapor/__tests__/directives.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { makeRender } from './_utils'
1919

2020
const define = makeRender()
2121

22-
describe('directives', () => {
22+
describe.todo('directives', () => {
2323
it('should work', async () => {
2424
const count = ref(0)
2525

packages/runtime-vapor/__tests__/directives/directives.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { makeRender } from '../_utils'
1515

1616
const define = makeRender()
1717

18-
describe('directives', () => {
18+
describe.todo('directives', () => {
1919
it('should work', async () => {
2020
const count = ref(0)
2121

packages/runtime-vapor/__tests__/directives/vModel.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const setDOMProps = (el: any, props: Array<[key: string, value: any]>) => {
2727
})
2828
}
2929

30-
describe('directive: v-model', () => {
30+
describe.todo('directive: v-model', () => {
3131
test('should work with text input', async () => {
3232
const spy = vi.fn()
3333

packages/runtime-vapor/__tests__/directives/vShow.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const createDemo = (defaultValue: boolean) =>
2828
on(n1 as HTMLElement, 'click', () => handleClick)
2929
return n0
3030
})
31-
describe('directive: v-show', () => {
31+
describe.todo('directive: v-show', () => {
3232
test('basic', async () => {
3333
const { host } = createDemo(true).render()
3434
const btn = host.querySelector('button')

packages/runtime-vapor/__tests__/for.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ describe('createFor', () => {
194194
expect(host.innerHTML).toBe('<!--for-->')
195195
})
196196

197-
test('should work with directive hooks', async () => {
197+
test.fails('should work with directive hooks', async () => {
198198
const calls: string[] = []
199199
const list = ref([0])
200200
const update = ref(0)

packages/runtime-vapor/__tests__/if.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ describe('createIf', () => {
134134
expect(host.innerHTML).toBe('<!--if-->')
135135
})
136136

137-
test('should work with directive hooks', async () => {
137+
test.todo('should work with directive hooks', async () => {
138138
const calls: string[] = []
139139
const show1 = ref(true)
140140
const show2 = ref(true)

packages/runtime-vapor/src/apiCreateFor.ts

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import {
2+
type EffectScope,
23
type ShallowRef,
3-
getCurrentScope,
4+
effectScope,
45
isReactive,
56
proxyRefs,
67
shallowRef,
7-
traverse,
88
triggerRef,
99
} from '@vue/reactivity'
1010
import { isArray, isObject, isString } from '@vue/shared'
@@ -18,17 +18,11 @@ import { type Block, type Fragment, fragmentKey } from './apiRender'
1818
import { warn } from './warning'
1919
import { currentInstance } from './component'
2020
import { componentKey } from './component'
21-
import { BlockEffectScope, isRenderEffectScope } from './blockEffectScope'
22-
import {
23-
createChildFragmentDirectives,
24-
invokeWithMount,
25-
invokeWithUnmount,
26-
invokeWithUpdate,
27-
} from './directivesChildFragment'
2821
import type { DynamicSlot } from './componentSlots'
22+
import { renderEffect } from './renderEffect'
2923

3024
interface ForBlock extends Fragment {
31-
scope: BlockEffectScope
25+
scope: EffectScope
3226
state: [
3327
item: ShallowRef<any>,
3428
key: ShallowRef<any>,
@@ -53,34 +47,24 @@ export const createFor = (
5347
let oldBlocks: ForBlock[] = []
5448
let newBlocks: ForBlock[]
5549
let parent: ParentNode | undefined | null
56-
const update = getMemo ? updateWithMemo : updateWithoutMemo
57-
const parentScope = getCurrentScope()!
5850
const parentAnchor = __DEV__ ? createComment('for') : createTextNode()
5951
const ref: Fragment = {
6052
nodes: oldBlocks,
6153
[fragmentKey]: true,
6254
}
6355

6456
const instance = currentInstance!
65-
if (__DEV__ && (!instance || !isRenderEffectScope(parentScope))) {
57+
if (__DEV__ && !instance) {
6658
warn('createFor() can only be used inside setup()')
6759
}
6860

69-
createChildFragmentDirectives(
70-
parentAnchor,
71-
() => oldBlocks.map(b => b.scope),
72-
// source getter
73-
() => traverse(src(), 1),
74-
// init cb
75-
getValue => doFor(getValue()),
76-
// effect cb
77-
getValue => doFor(getValue()),
78-
once,
79-
)
61+
const update = getMemo ? updateWithMemo : updateWithoutMemo
62+
once ? renderList() : renderEffect(renderList)
8063

8164
return ref
8265

83-
function doFor(source: any) {
66+
function renderList() {
67+
const source = src()
8468
const newLength = getLength(source)
8569
const oldLength = oldBlocks.length
8670
newBlocks = new Array(newLength)
@@ -265,7 +249,7 @@ export const createFor = (
265249
idx: number,
266250
anchor: Node = parentAnchor,
267251
): ForBlock {
268-
const scope = new BlockEffectScope(instance, parentScope)
252+
const scope = effectScope()
269253

270254
const [item, key, index] = getItem(source, idx)
271255
const state = [
@@ -283,11 +267,9 @@ export const createFor = (
283267
})
284268
block.nodes = scope.run(() => renderItem(proxyRefs(state)))!
285269

286-
invokeWithMount(scope, () => {
287-
// TODO v-memo
288-
// if (getMemo) block.update()
289-
if (parent) insert(block.nodes, parent, anchor)
290-
})
270+
// TODO v-memo
271+
// if (getMemo) block.update()
272+
if (parent) insert(block.nodes, parent, anchor)
291273

292274
return block
293275
}
@@ -326,7 +308,6 @@ export const createFor = (
326308
}
327309

328310
if (needsUpdate) setState(block, newItem, newKey, newIndex)
329-
invokeWithUpdate(block.scope)
330311
}
331312

332313
function updateWithoutMemo(
@@ -344,13 +325,11 @@ export const createFor = (
344325
(!isReactive(newItem) && isObject(newItem))
345326

346327
if (needsUpdate) setState(block, newItem, newKey, newIndex)
347-
invokeWithUpdate(block.scope)
348328
}
349329

350330
function unmount({ nodes, scope }: ForBlock) {
351-
invokeWithUnmount(scope, () => {
352-
removeBlock(nodes, parent!)
353-
})
331+
removeBlock(nodes, parent!)
332+
scope.stop()
354333
}
355334
}
356335

Lines changed: 22 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
1+
import { renderEffect } from './renderEffect'
12
import { type Block, type Fragment, fragmentKey } from './apiRender'
2-
import { getCurrentScope } from '@vue/reactivity'
3+
import { type EffectScope, effectScope } from '@vue/reactivity'
34
import { createComment, createTextNode, insert, remove } from './dom/element'
4-
import { currentInstance } from './component'
5-
import { warn } from './warning'
6-
import { BlockEffectScope, isRenderEffectScope } from './blockEffectScope'
7-
import {
8-
createChildFragmentDirectives,
9-
invokeWithMount,
10-
invokeWithUnmount,
11-
invokeWithUpdate,
12-
} from './directivesChildFragment'
135

146
type BlockFn = () => Block
157

@@ -26,46 +18,25 @@ export const createIf = (
2618
let branch: BlockFn | undefined
2719
let parent: ParentNode | undefined | null
2820
let block: Block | undefined
29-
let scope: BlockEffectScope | undefined
30-
const parentScope = getCurrentScope()!
21+
let scope: EffectScope | undefined
3122
const anchor = __DEV__ ? createComment('if') : createTextNode()
3223
const fragment: Fragment = {
3324
nodes: [],
3425
anchor,
3526
[fragmentKey]: true,
3627
}
3728

38-
const instance = currentInstance!
39-
if (__DEV__ && (!instance || !isRenderEffectScope(parentScope))) {
40-
warn('createIf() can only be used inside setup()')
41-
}
42-
4329
// TODO: SSR
4430
// if (isHydrating) {
4531
// parent = hydrationNode!.parentNode
4632
// setCurrentHydrationNode(hydrationNode!)
4733
// }
4834

49-
createChildFragmentDirectives(
50-
anchor,
51-
() => (scope ? [scope] : []),
52-
// source getter
53-
condition,
54-
// init cb
55-
getValue => {
56-
newValue = !!getValue()
57-
doIf()
58-
},
59-
// effect cb
60-
getValue => {
61-
if ((newValue = !!getValue()) !== oldValue) {
62-
doIf()
63-
} else if (scope) {
64-
invokeWithUpdate(scope)
65-
}
66-
},
67-
once,
68-
)
35+
if (once) {
36+
doIf()
37+
} else {
38+
renderEffect(() => doIf())
39+
}
6940

7041
// TODO: SSR
7142
// if (isHydrating) {
@@ -75,17 +46,20 @@ export const createIf = (
7546
return fragment
7647

7748
function doIf() {
78-
parent ||= anchor.parentNode
79-
if (block) {
80-
invokeWithUnmount(scope!, () => remove(block!, parent!))
81-
}
82-
if ((branch = (oldValue = newValue) ? b1 : b2)) {
83-
scope = new BlockEffectScope(instance, parentScope)
84-
fragment.nodes = block = scope.run(branch)!
85-
invokeWithMount(scope, () => parent && insert(block!, parent, anchor))
86-
} else {
87-
scope = block = undefined
88-
fragment.nodes = []
49+
if ((newValue = !!condition()) !== oldValue) {
50+
parent ||= anchor.parentNode
51+
if (block) {
52+
scope!.stop()
53+
remove(block, parent!)
54+
}
55+
if ((branch = (oldValue = newValue) ? b1 : b2)) {
56+
scope = effectScope()
57+
fragment.nodes = block = scope.run(branch)!
58+
parent && insert(block, parent, anchor)
59+
} else {
60+
scope = block = undefined
61+
fragment.nodes = []
62+
}
8963
}
9064
}
9165
}

0 commit comments

Comments
 (0)