20

I have a (parent) component in Vue that ships with it's own on-screen keyboard which is in it's own Vue component. The keyboard keeps track of the entered value and passes this value to the parent component. Sometimes the parent component needs to reset the value.

The way it is currently implemented is by directly modifying the prop that is passed to the keyboard. That obviously yields the warning Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders.. However, this is exactly the behaviour I expect in this case: The variables are in sync, and should stay in sync if the parent changes the value. In other words: I want to disable this specific warning for this specific component.

I could add a watcher to the property that overwrites a local variable and use the local variable instead to keep track of things. That's... silly, as it does exactly what it does now, with more variables to keep track of. I have however not found a way to squelch warnings yet. Is there such a feature?

Sumurai8
  • 20,333
  • 11
  • 66
  • 100
  • You don't even need a watcher: just use a computed property or an internal data store: http://stackoverflow.com/questions/39868963/vue-2-mutating-props-vue-warn – Terry May 12 '17 at 08:57
  • Both the parent and the child need access to the variable, and they can't access each others variables except through the prop/event system. With internal data store I guess you mean vuex's datastore? That seems overkill, as I don't want the value to persist beyond where the parent and child are actually displayed. – Sumurai8 May 12 '17 at 09:28
  • 1
    One way might be to pass the property as an object, with the relevant info as properties of the object. Vue won't complain because you're not mutating the reference to the object. – Bert May 12 '17 at 15:24

2 Answers2

13

As per Linux Borg (core dev) it is currently (Vue 2.5.17) not possible to disable any warnings on a per-component basis. You can use the Vue.config.silent option to silence all warnings.

tony19
  • 125,647
  • 18
  • 229
  • 307
Sumurai8
  • 20,333
  • 11
  • 66
  • 100
  • 1
    As of the question, this answer is already old. For so long time now, both Vue 2 and Vue 3 (and Nuxt) allow to customize Vue warnings behavior, as shown [here](https://stackoverflow.com/a/74496033/424498). – Erick Petrucelli Nov 18 '22 at 22:46
1

Before you think on mutating props...

Playing with prop mutation is generally wrong, as it's clearly stated in the documentation about props and the One-Way Data Flow:

All props form a one-way-down binding between the child property and the parent one: when the parent property updates, it will flow down to the child, but not the other way around. This prevents child components from accidentally mutating the parent's state, which can make your app's data flow harder to understand.

Being very pragmatic here, most times someone faces the need of tricking it, in fact the component is being created in an equivocated way.

Now answering about disabling specific Vue warnings:

Anyway, there are valid cases when disabling specific Vue warnings may fit, like when you're using Storybook with Vue and intentionally mutating some props (and don't want to keep seeing all that warnings logged as errors in your console), or when you're hacking something in Vue internals in a very advanced way (and while dangerous, you're doing so in a very conscious way).

So, for that use cases, just leverage Vue.config.warnHandler in Vue 2:

Vue.config.warnHandler = (msg, instance, trace) =>
  ![
    'built-in or reserved HTML elements as component id: component',
    '"class" is a reserved attribute and cannot be used as component prop',
    'Cannot find element: #__nuxt'
  ].some((warning) => msg.includes(warning)) &&
  console.warn('[Vue warn]: '.concat(msg).concat(trace))

The above example avoids logging warnings containing any of the three strings provided inside the Array, and logs any other accepted message as a console.warn (instead of the default console.error). Feel free to adjust the unwanted messages Array as needed, or even to change all the logic as needed.

The same example, but with createApp then app.config.warnHandler for Vue 3:

import { createApp } from 'vue'

const app = createApp({
  /* root component options */
})

app.config.warnHandler = (msg, instance, trace) =>
  ![
    'built-in or reserved HTML elements as component id: component',
    '"class" is a reserved attribute and cannot be used as component prop',
    'Cannot find element: #__nuxt'
  ].some((warning) => msg.includes(warning)) &&
  console.warn('[Vue warn]: '.concat(msg).concat(trace))

Worth to observe that Nuxt also allows to adjust Vue.config inside nuxt.config.js:

export default {
  /* Other Nuxt.config options */

  vue: {
    config: {
      warnHandler: (msg, instance, trace) =>
        ![
          'built-in or reserved HTML elements as component id: component',
          '"class" is a reserved attribute and cannot be used as component prop',
          'Cannot find element: #__nuxt'
        ].some((warning) => msg.includes(warning)) &&
        console.warn('[Vue warn]: '.concat(msg).concat(trace))
    }
  }
}
Erick Petrucelli
  • 14,386
  • 8
  • 64
  • 84