expect(serializeInner(root)).toBe(`<button>Step</button><p>Step 2</p>`)
})
- it('manual trigger computed', () => {
+ test('manual trigger computed', () => {
const cValue = computed(() => 1)
triggerRef(cValue)
expect(cValue.value).toBe(1)
})
+
+ test('computed should remain live after losing all subscribers', () => {
+ const toggle = ref(true)
+ const state = reactive({
+ a: 1,
+ })
+ const p = computed(() => state.a + 1)
+ const pp = computed(() => {
+ return toggle.value ? p.value : 111
+ })
+
+ const { effect: e } = effect(() => pp.value)
+ e.stop()
+
+ expect(p.value).toBe(2)
+ state.a++
+ expect(p.value).toBe(3)
+ })
})
}
}
-function removeSub(link: Link) {
+function removeSub(link: Link, fromComputed = false) {
const { dep, prevSub, nextSub } = link
if (prevSub) {
prevSub.nextSub = nextSub
// value can be GCed
dep.computed.flags &= ~EffectFlags.TRACKING
for (let l = dep.computed.deps; l; l = l.nextDep) {
- removeSub(l)
+ removeSub(l, true)
}
- } else if (dep.map) {
+ } else if (dep.map && !fromComputed) {
// property dep, remove it from the owner depsMap
dep.map.delete(dep.key)
if (!dep.map.size) targetMap.delete(dep.target!)