Skip to content

Commit ba17fb9

Browse files
authored
fix(runtime-vapor): trigger updated hooks across components (#165)
1 parent 78f74ce commit ba17fb9

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import {
2+
type InjectionKey,
3+
type Ref,
4+
createComponent,
5+
createTextNode,
6+
getCurrentInstance,
7+
inject,
8+
nextTick,
9+
onUpdated,
10+
provide,
11+
ref,
12+
renderEffect,
13+
setText,
14+
} from '../src'
15+
import { makeRender } from './_utils'
16+
17+
const define = makeRender<any>()
18+
19+
describe('apiLifecycle', () => {
20+
// TODO: test
21+
22+
// #136
23+
test('should trigger updated hooks across components. (parent -> child)', async () => {
24+
const handleUpdated = vi.fn()
25+
const handleUpdatedChild = vi.fn()
26+
27+
const count = ref(0)
28+
29+
const { render, host } = define({
30+
setup() {
31+
onUpdated(() => handleUpdated())
32+
return (() => {
33+
const n0 = createTextNode()
34+
renderEffect(() => setText(n0, count.value))
35+
const n1 = createComponent(Child, { count: () => count.value })
36+
return [n0, n1]
37+
})()
38+
},
39+
})
40+
41+
const Child = {
42+
props: { count: Number },
43+
setup() {
44+
onUpdated(() => handleUpdatedChild())
45+
return (() => {
46+
const props = getCurrentInstance()!.props
47+
const n2 = createTextNode()
48+
renderEffect(() => setText(n2, props.count))
49+
return n2
50+
})()
51+
},
52+
}
53+
54+
render()
55+
56+
expect(host.innerHTML).toBe('00')
57+
expect(handleUpdated).toHaveBeenCalledTimes(0)
58+
expect(handleUpdatedChild).toHaveBeenCalledTimes(0)
59+
60+
count.value++
61+
await nextTick()
62+
expect(host.innerHTML).toBe('11')
63+
expect(handleUpdated).toHaveBeenCalledTimes(1)
64+
expect(handleUpdatedChild).toHaveBeenCalledTimes(1)
65+
})
66+
67+
// #136
68+
test('should trigger updated hooks across components. (child -> parent)', async () => {
69+
const handleUpdated = vi.fn()
70+
const handleUpdatedChild = vi.fn()
71+
72+
const key: InjectionKey<Ref<number>> = Symbol()
73+
74+
const { render, host } = define({
75+
setup() {
76+
const count = ref(0)
77+
provide(key, count)
78+
onUpdated(() => handleUpdated())
79+
return (() => {
80+
const n0 = createTextNode()
81+
renderEffect(() => setText(n0, count.value))
82+
const n1 = createComponent(Child, { count: () => count.value })
83+
return [n0, n1]
84+
})()
85+
},
86+
})
87+
88+
let update: any
89+
const Child = {
90+
props: { count: Number },
91+
setup() {
92+
onUpdated(() => handleUpdatedChild())
93+
const count = inject(key)!
94+
update = () => count.value++
95+
return (() => {
96+
const n2 = createTextNode()
97+
renderEffect(() => setText(n2, count.value))
98+
return n2
99+
})()
100+
},
101+
}
102+
103+
render()
104+
105+
expect(host.innerHTML).toBe('00')
106+
expect(handleUpdated).toHaveBeenCalledTimes(0)
107+
expect(handleUpdatedChild).toHaveBeenCalledTimes(0)
108+
109+
update()
110+
await nextTick()
111+
expect(host.innerHTML).toBe('11')
112+
expect(handleUpdated).toHaveBeenCalledTimes(1)
113+
expect(handleUpdatedChild).toHaveBeenCalledTimes(1)
114+
})
115+
})

packages/runtime-vapor/src/apiRender.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ function mountComponent(
106106

107107
insert(instance.block!, instance.container)
108108
instance.isMounted = true
109+
instance.comps.forEach(comp => {
110+
comp.isMounted = true
111+
})
109112

110113
// hook: mounted
111114
invokeLifecycle(instance, VaporLifecycleHooks.MOUNTED, 'mounted', true)

0 commit comments

Comments
 (0)