Test cases to add. Mutating a reactive parent.
Just added these test cases for when mutating a reactive parent. I ran into the second issue realising the ref which I created had been overwritten. Don't know if this warning should be added to the docs which "watchers to refs that have been overwritten at the parent level will not fire".
test('should work with mutating parent', (assert) => {
let state = reactive({
settings: {
blocking: {
isEnabled: false,
isCosmetic: false,
whitelist: []
}
}
})
let triggered = 0
const stop = watch(() => {
return state.settings.blocking
}, () => {
triggered += 1
})
state.settings = {
blocking: {
isEnabled: true,
isCosmetic: true,
whitelist: []
}
}
assert.is(triggered, 1)
stop()
})
test('should not trigger when mutating parent because watching a ref that has been destroyed by the parent mutation.', (assert) => {
let state = reactive({
settings: {
blocking: {
isEnabled: false,
isCosmetic: false,
whitelist: []
}
}
})
let triggered = 0
const refBlocking = ref(state.settings.blocking)
const stop = watch(refBlocking, () => {
triggered += 1
})
state.settings = {
blocking: {
isEnabled: true,
isCosmetic: true,
whitelist: []
}
}
assert.is(triggered, 0)
stop()
})
@Lee182 This is not how you use it, instead of
const refBlocking = ref(state.settings.blocking)
You should do
const refBlocking = toRef(state.settings, 'blocking')
See more on Vue 3's caveat. Thanks
Tried const refBlocking = toRef(state.settings, 'blocking'). That fails.
As a point of discussion should there be some sort of deep to ref function like lodash.get.
_.get(state, 'settings.blocking'
watch on master [!] is 📦 v0.1.6 via ⬢ v12.18.3 took 6s
❯ pnpm run test
> @vue-reactivity/[email protected] test C:\me\dev\tabdeck\external_lib\watch
> c8 ava
should not trigger when mutating parent because watching a ref that has been destroyed by the parent mutation.
test\watch.spec.ts:128
127:
128: assert.is(triggered, 1)
129: stop()
Difference:
- 0
+ 1
» test/watch.spec.ts:128:10
─
1 test failed
------------------|---------|----------|---------|---------|-------------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------------|---------|----------|---------|---------|-------------------------
All files | 94.18 | 100 | 88.46 | 94.18 |
errorHandling.ts | 98.28 | 100 | 66.67 | 98.28 | 58
index.ts | 93.16 | 100 | 91.3 | 93.16 | 47-56,74-75,116-118,122
------------------|---------|----------|---------|---------|-------------------------
ERROR Test failed. See above for more details.
In my project base I've got round it using watchEffect. I just then had to mannually track changes which I know from reading the docs which watch will track changes and call the callback only on change. lazy is what the docs call this behaviour.
this.stopWatchSettings = watchEffect(() => {
// const blocker = state.settings.blocker
const blocker = _.get(state, 'settings.blocker')
this.swapBlocker({})
}, { flush: 'post' })