Subscribe on changes!

`watch` runs while the component is being unmounted

avatar
Nov 4th 2022

Vue version

3.2.41

Link to minimal reproduction

Steps to reproduce

  1. Click /users/b button.
  2. Click /users button.
  3. Check the console (will show the id: undefined).

What is expected?

The behavior should be the same as /users/b to /about simply destroying the component without triggering watch().

What is actually happening?

The behavior is the same as /users/b to /users/a to reuse component instances and then trigger watch() (trigger watch() again before destroying the component instance?).

System Info

System:
  OS: Linux 5.0 undefined
  CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
  Memory: 0 Bytes / 0 Bytes
  Shell: 1.0 - /bin/jsh
Binaries:
  Node: 16.14.2 - /usr/local/bin/node
  Yarn: 1.22.19 - /usr/local/bin/yarn
  npm: 7.17.0 - /usr/local/bin/npm
npmPackages:
  vue: ^3.2.41 => 3.2.41

Any additional comments?

Is this expected behavior? It seems annoying to need to add a condition of undefined to the watch() callback.

Not sure #2291 has fixed the problem

I will be grateful for any help any can provide!

avatar
Nov 4th 2022

Could you try reproducing it with Vue as mentioned at https://github.com/posva/unplugin-vue-router/issues/86#issuecomment-1302645233 please?

avatar
Nov 14th 2022

I have the same problem with route.query watcher - it fires when I leave "current" page and route queries on both pages are {}. "vue": "3.2.45", "vue-router": "4.1.6"

avatar
Nov 19th 2022

Here is this reproduction with Vue only. And I create a PR to fix it. Feel free to review it.

The key point to reproduce the problem is to change the props. And in the RouterView component, the changed prop is onVnodeUnmounted.

avatar
May 8th 2023

Hey, would like to push this because this issue has implications if you run e.g. requests in a watcher. There will be redundant requests with potentially invalid values. In a project that I'm working on we have a lot of logspam because of it.

avatar
May 16th 2023

This seems to also be related https://github.com/vuejs/core/issues/6811. And this linked PR https://github.com/vuejs/core/pull/7009.

avatar
Oct 19th 2023

@posva since you closed my issue can you offer a signal of intent for this issue? This is marked as a minor issue but anybody migrating from Vue 2 is probably experiencing this issue whether they realize it or not. Our code base consists of thousands of components across hundreds of pages. It’s not possible to test the fallout from this bug, the surface area is pretty much everything.

avatar
Oct 19th 2023

The easiest workaround is to use flush: post for your watchers. It's been mentioned in other related issues but it's getting difficult to find now

avatar
Oct 19th 2023

One man’s “easiest” is another man’s “thousands of changes and infinite test surface”…

Might as well close this issue if there’s no intent to fix the discrepancy.

avatar
Oct 19th 2023

It has other implications to use flush: post because it changes the time when the watcher is called. I think it needs a fix. Calling a watcher of a component that is unmounted feels like a bug.

avatar
Oct 19th 2023

It's just a workaround 😉 . I'm adding it in case it helps some folks. Hopefully the PR can be merged for the next release

avatar
Nov 8th 2023

Just hit this issue, exact as described by OP. I was going crazy over what the cause was. but eventually tracked it down to the watcher and the only funny part of this story is that I had this issue before (but router-related) and had a comment pointing to this and other related threads 😅

🤞 for the PR