Watch (flush: 'sync') (which is not bound to component live cycle) is not respected in server renderer.
Vue version
3.2.36
Link to minimal reproduction
https://codesandbox.io/s/vue-ssr-watch-sync-bug-xr5jql?file=/src/App.vue:115-356
Steps to reproduce
Make setup function does things as such
<template>
<div>{{test2}}</div>
</template>
<script>
import {ref, watch} from 'vue'
export default {
setup() {
const testRef = ref(0)
let test2 = 0
watch(testRef, () => {
test2 = 1
}, { flush: 'sync' })
testRef.value = 1
// eslint-disable-next-line no-console
console.log(testRef, test2)
return {
test2
}
}
}
</script>
And run it in the ssr server environment
What is expected?
Both server returned result and client rendering should returns 1 because everything happened before returning from setup ()
.
Watch with flush: 'sync'
should be respected as it don't use component live cycle
What is actually happening?
The server html returns 0.
Watch on ssr is ignored unconditionally
System Info
System:
OS: Linux 5.4 Ubuntu 20.04.2 LTS (Focal Fossa)
CPU: (8) x64 AMD Ryzen 9 5950X 16-Core Processor
Memory: 1.01 GB / 15.64 GB
Container: Yes
Shell: 5.0.17 - /bin/bash
Binaries:
Node: 14.15.0 - ~/.nvm/versions/node/v14.15.0/bin/node
Yarn: 1.22.10 - ~/.nvm/versions/node/v14.15.0/bin/yarn
npm: 6.14.8 - ~/.nvm/versions/node/v14.15.0/bin/npm
Browsers:
Chrome: 92.0.4515.131
Chromium: 101.0.4951.64
Firefox: 90.0.2
Firefox Nightly: 60.0a1
Any additional comments?
Context:
I am using pinia store in SSR (nuxts) and try to persist data to cookie with the $subscribe
method of pinia store.
But the callback never runs even specify { flush: 'sync' }
.
So I always get empty cookie.
After a bit of trace,
I found the $subscribe
use watch
to achieve the update notifying
And vue ignored watch (even 'sync', which is completely unrelated to component live cycle) in ssr mode.