Attributes and listeners inheritance in Vue.js

When developing any application with Vue.js, you probably need to create some kind of input field component for your forms. Moreover, the fields can vary from each other with many details like labels, hints, prefixes, suffixes, icons, validation messages, etc.

Many types of input fields can be included in the application forms

From the HTML point of view, the input field itself is not enough to achieve this. Obviously, there is more markup needed. Consider the following code as examples:

Default input:

<input type="text" placeholder="Default input" name="example" />Code language: HTML, XML (xml)

Input with hint:

<input type="text" placeholder="Default input" name="example" />
<div>Nam pretium mi tempor eros interdum.</div>Code language: HTML, XML (xml)

Input with label:

<label>
  <div>Name</div>
  <input type="text" placeholder="Default input" name="example" />
</label>Code language: HTML, XML (xml)

Input with prefix:

<div>
  <div>Prefix</div>
  <input type="text" placeholder="Default input" name="example" />
</div>
Code language: HTML, XML (xml)

Input with suffix:

<div>
  <input type="text" placeholder="Default input" name="example" />
  <div>Suffix</div>
</div>Code language: HTML, XML (xml)

All in one:

<label>
  <div>Name</div>
  <div>  
    <div>Prefix</div>
    <input type="text" placeholder="Default input" name="example" />
    <div>Suffix</div>
  </div>
  <div>Nam pretium mi tempor eros interdum.</div>
</label>Code language: HTML, XML (xml)

Applying v-model directive and listeners to created component

When you apply the v-model directive to the component like this:

<InputField v-model="inputValue"/>Code language: HTML, XML (xml)

it would not work to update the input value and listen to any changes if the component markup is wrapped with some additional elements (like in the example). This happens because of the default attributes and listeners inheritance behavior. Vue would bind those to the component wrapping element out of the box. This is a problem when we want to update the form state by listening to the input event or pass the value by the v-model. Fortunately, the behavior can be adjusted with a component property called inheritAttrs. You can use it in the component script alongside data, methods, watchers, lifehooks, etc.:

<script>
  export default {
    name: 'input-field',
    data: {
      inputValue: ''
    },
    inheritAttrs: false
    // [...]
  }
</script>Code language: JavaScript (javascript)

With inheritAttrs attribute set to false, Vue would not bind the attributes and listeners to the wrapping element. Instead, a programmer can decide where those should be bound. To do this, bind global variables $attrs and $listeners to the input element:

<label>
  <div>Name</div>
  <div>  
    <div>Prefix</div>
    <input type="text" placeholder="Default input" name="example" v-bind="$attrs" v-on="$listeners" />
    <div>Suffix</div>
  </div>
  <div>Nam pretium mi tempor eros interdum.</div>
</label>Code language: HTML, XML (xml)

With this, all events would be emitted to the parent component, and props would be passed down to the element.

By default, parent scope attribute bindings that are not recognized as props will “fallthrough” and be applied to the root element of the child component as normal HTML attributes. When authoring a component that wraps a target element or another component, this may not always be the desired behavior. By setting inheritAttrs to false, this default behavior can be disabled. The attributes are available via the $attrs instance property (also new in 2.4) and can be explicitly bound to a non-root element using v-bind. Note: this option does not affect class and style bindings.

https://vuejs.org/v2/api/#inheritAttrs

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Calling all proficient WordPress gurus and agencies! Are you in search of a way to optimize your time and resources while still providing your clients with exceptional websites? In that case, Astratic Theme is the definitive solution for you.

Topics

AJAX astratic Attribute inheritance backup blocks bounce rate code smell Coditive Contact Form cronjobs custom blocks database formatting rules GIT Git Flow GitHub Flow GitLab Flow JavScript loading speed MAMP message broker nuxt nuxt3 overlays patterns PHP PHP rules plugin Popups Post Draft Preview RabbitMQ schedule Simple Customizations for WooCommerce Simple Floating Contact Form software development Vue.js web development WooCommerce WordPress WordPress CLI WordPress Gutenberg Wordpress plugins WordPress updates WP-CLI wp-cron