Vue-next: [Vue warn]: Avoid app logic that relies on enumerating keys on a component instance. The keys will be empty in production mode to avoid performance overhead.

Created on 2 Sep 2020  ·  9Comments  ·  Source: vuejs/vue-next

Version

3.0.0-rc.9

Reproduction link

https://github.com/rothskeller/vuewarnreport

Steps to reproduce

  • git clone
  • yarn install
  • yarn dev
  • click on links in demo

What is expected?

No warning.

### What is actually happening?

First, note that this is the same symptom as #1991 but not the same cause.

This is happening because of the call to watch(route, ...) which is made in client/src/pages/ID.vue. The route object has within it a reference to the component, so watching the route includes watching the component, which triggers the warning. But watching the route for changes is a typical, and indeed essential, idiom in vue-router which should not result in a console warning. I don't know whether this should be considered a vue-next bug or a vue-router-next bug, but I'm guessing the former.

Most helpful comment

watch(route) is implicitly deep: true, which traverses arbitrarily deep properties. So technically, this is expected behavior. Also, deep traversing a complex object when you only care about a few properties is wasteful.

Your use case can and should be rewritten using a computed property instead:

const id = computed(() => {
   return Array.isArray(route.params.id) ? route.params.id[0] : route.params.id
})

If you must use a watcher, you should also use watchEffect and avoid deep watches:

watchEffect(() => {
  id.value = Array.isArray(route.params.id) ? route.params.id[0] : route.params.id
})

All 9 comments

watch(route) is implicitly deep: true, which traverses arbitrarily deep properties. So technically, this is expected behavior. Also, deep traversing a complex object when you only care about a few properties is wasteful.

Your use case can and should be rewritten using a computed property instead:

const id = computed(() => {
   return Array.isArray(route.params.id) ? route.params.id[0] : route.params.id
})

If you must use a watcher, you should also use watchEffect and avoid deep watches:

watchEffect(() => {
  id.value = Array.isArray(route.params.id) ? route.params.id[0] : route.params.id
})

@yyx990803 Your response makes sense, but permit me to note that it disagrees with the documentation for view-router-next, which explicitly calls for watching the route object. I do not know how to reconcile between two core Vue projects.

Can you point me the part of the documentation so I can take a look?

@posva I see two references: here and here.

Thanks!

@yyx990803 How about setting watch(route, () => {}, { deep: false }) instead? Can I avoid deep watch as well?

watch(route) is implicitly deep: true, which traverses arbitrarily deep properties. So technically, this is expected behavior. Also, deep traversing a complex object when you only care about a few properties is wasteful.

Your use case can and should be rewritten using a computed property instead:

const id = computed(() => {
   return Array.isArray(route.params.id) ? route.params.id[0] : route.params.id
})

If you must use a watcher, you should also use watchEffect and avoid deep watches:

watchEffect(() => {
  id.value = Array.isArray(route.params.id) ? route.params.id[0] : route.params.id
})

我在vue3 中试用了 vue2 的watch: { $route(newVal, oldVal) {...}} 也会看到这个报警, 这个怎么解决?

vue3 中,这个是devtools 6.0.0 beta 2打印的,我把devtools关闭,这个waring就消失了

Close vue-devtools and the warning will disappear. This should be the problem with DevTools

Was this page helpful?
0 / 5 - 0 ratings

Related issues

anandkumarram picture anandkumarram  ·  4Comments

NMFES picture NMFES  ·  3Comments

harrytran998 picture harrytran998  ·  3Comments

skirtles-code picture skirtles-code  ·  3Comments

HakamFostok picture HakamFostok  ·  3Comments