Quick Attrs to Child Components and Elements


#1

I created a function, that I would add into a component that would allow it to receive additional props/element attributes that I could pass directly down from the parent.

So this is the function that does the work:

getAttrs(attrs, element = null, deliminator = ':') => {
    if (element) {
      const prefix = element + deliminator;
      return Object
        .keys(attrs)
        .filter(key => key.indexOf(prefix) === 0)
        .reduce((output, key) => {
          output[key.replace(prefix, '')] = attrs[key];
          return output;
        }, {});
    } else {
      return Object
        .keys(attrs)
        .filter(key => key.indexOf(deliminator) < 0)
        .reduce((output, key) => {
          output[key] = attrs[key];
          return output;
        }, {});
    }
  };

In action the getAtts() function requires vue instance’s $attrs as the first argument, then some kind of identifier that is used before the deliminator (defaulted to a ‘:’), which itself separates the identifier and the attribute/prop you are trying to pass. This will also work with v-bind.

Example

// child-component.vue

<template>
  <div v-bind="getAttrs()">
    <input v-bind="getAttrs('textInput')" class="my-input" type="text">
  </div>
</template>
<script>
  import getAttrs from 'path/to/getAttrs.js';
  export default {
    // required to be placed component in order to work
    inheritAttrs: false
    methods: {
      getAttrs (element) {
         return getAttrs(this.$attrs, element);
      }
  };
</script>

// parent-component.vue
<template>
  <ChildComponent :textInput:class="['another-class', 'yet-another-class']" textInput:name="fullname" />
</template>

Although a very simple example, the above will allow the “ChildComponent” to accept dynamic classes and other attributes to any specific element below. The getAttrs() was applied to the root element as well to guarantee that the root element will receive the correct attributes that it normally would if no “namespace/identifier” is provided. These namespaced items also work with v-bind or ‘:’ even though the deliminator is ‘:’.