Search code examples
vue.jsvue-component

Pass specific $attrs parameter to Vue component


I have the following code in my parent component:

<TestVIsComponent :post="somepost" :somevalue="17" data-status="activated" data-feature="new" @change="submitChange"></TestVIsComponent>

And the following child component:

  <div>
     <h1 v-bind="$attrs">{{post.id}}</h1>
  </div>

This code and the $attrs would pass the data-status="activated" data-feature="new" attributes to the H1 tag instead of the div which is the desired result. Here is the result:

<h1 data-status="activated" data-feature="new">1</h1>

However, is there a way to pass only one attribute to the H1 tag? Is there a way to somehow iterate the $attrs in the child? Something like attrs[0] or attrs['attribute_name']? I need to achieve the following or similar:

  <div>
     <h1 v-bind="$attrs[0]">{{post.id}}</h1>
     <h3 v-bind="$attrs[1]">{{post.something}}</h3>
  </div>

Solution

  • If you know what attributes are for div element then you should use them as props instead of $attrs.

    or you can split $attrs

    <template>
    <div v-bind="divAttrs">
       <h1 v-bind="h1Attrs">{{post.id}}</h1>
    </div>
    </template>
    <script>
    export default {
       computed: {
         divAttrs () {
           const allowed = ['data-status', 'data-feature']
           return Object.keys(this.$attrs)
             .filter(key => allowed.includes(key))
             .reduce((obj, key) => {
               obj[key] = this.$attrs[key]
               return obj
             }, {})
         },
         h1Attrs () {
           const notAllowed = ['data-status', 'data-feature']
           return Object.keys(this.$attrs)
             .filter(key => !notAllowed.includes(key))
             .reduce((obj, key) => {
               obj[key] = this.$attrs[key]
               return obj
             }, {})
         }
       }
    }
    </script>