Vue.js 3.0 Tutorial

Vue.js 3.0 Component Advanced

Vue.js 3.0 Transitions & Animations

Vue.js 3.0 Reusable & Combinable

Vue.js 3.0 Advanced

Vue.js 3.0 Tools

Vue.js 3.0 Scale

Vue.js 3.0 Accessibility

Vue.js 3.0 Migrating from Vue2

Vue.js 3.0 Contribute Documentation

Vue.js 3.0 API References

Vue.js 3.0 Style Guide

Vue 3.0 non-Prop Attribute

In Vue, non-prop attributes are those that you add to a component, but are not defined as props in that component. Non-prop attributes are also referred to as "fall-through" attributes because they fall through the component and are included on its root element. This can be helpful for adding classes, styles, or native HTML attributes to the root element of a component.

Let's illustrate this with an example.

Step 1: Initialize your Vue project.

First, create a new Vue 3 project using Vue CLI:

npm install -g @vue/cli
vue create my-project

Choose Vue 3 when asked which version of Vue to use.

Step 2: Define a component.

In your src/components directory, create a new file called CustomButton.vue:

<template>
  <button>
    <slot></slot>
  </button>
</template>

In this example, we've created a simple CustomButton component.

Step 3: Use the component with non-prop attributes.

In another component (for example, App.vue), use the CustomButton component and add some non-prop attributes to it:

<template>
  <div id="app">
    <CustomButton class="btn" disabled>Click me</CustomButton>
  </div>
</template>

<script>
import CustomButton from './components/CustomButton.vue'

export default {
  components: {
    CustomButton
  }
}
</script>

<style>
.btn {
  background-color: #f00;
  color: #fff;
}
</style>

In this example, class and disabled are non-prop attributes. Since CustomButton doesn't have any props defined, Vue will apply these attributes to the root element of CustomButton, which is the button element.

Step 4: Run your application.

You can run your Vue 3 application with the following command:

npm run serve

Now if you load your application in a browser, you should see a red "Click me" button, which is disabled.

This is a basic example of how non-prop attributes work in Vue. It's worth mentioning that in Vue 3, you can define which attributes are inherited and which aren't by using the inheritAttrs option and the $attrs instance property.

  1. Vue 3.0 inheritAttrs Option:

    • The inheritAttrs option controls whether or not a component should inherit the attributes declared on the component to its root element.

    • When set to false, attributes are not automatically added to the root element.

    • Example code:

      <!-- ChildComponent.vue -->
      <template>
        <div :class="className">Child Component</div>
      </template>
      
      <script>
      export default {
        inheritAttrs: false,
        props: ['className'],
      };
      </script>
      
  2. Custom Components and Non-Prop Data in Vue 3.0:

    • Custom components can receive non-prop data through the v-bind="$attrs" directive.

    • This allows you to bind all non-prop attributes to an element within the custom component.

    • Example code:

      <!-- ParentComponent.vue -->
      <template>
        <child-component custom-attribute="value"></child-component>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          ChildComponent,
        },
      };
      </script>
      
      <!-- ChildComponent.vue -->
      <template>
        <div v-bind="$attrs">Child Component</div>
      </template>
      
      <script>
      export default {
        inheritAttrs: false,
      };
      </script>
      
  3. Vue 3.0 Non-Prop Attributes Behavior:

    • Non-prop attributes are attributes not defined in the props option of a component.

    • By default, Vue will automatically add non-prop attributes to the root element of a component.

    • Example code:

      <!-- ChildComponent.vue -->
      <template>
        <div>{{ nonPropAttribute }}</div>
      </template>
      
      <script>
      export default {
        props: ['propAttribute'],
      };
      </script>
      
      <!-- ParentComponent.vue -->
      <template>
        <child-component prop-attribute="value" non-prop-attribute="otherValue"></child-component>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          ChildComponent,
        },
      };
      </script>
      
  4. Default Behavior for Non-Prop Attributes in Vue 3.0:

    • By default, Vue automatically adds non-prop attributes to the root element of a component.

    • The inheritAttrs option can be used to control this behavior.

    • Example code (with default behavior):

      <!-- ChildComponent.vue -->
      <template>
        <div>{{ nonPropAttribute }}</div>
      </template>
      
      <script>
      export default {
        props: ['propAttribute'],
      };
      </script>
      
      <!-- ParentComponent.vue -->
      <template>
        <child-component prop-attribute="value" non-prop-attribute="otherValue"></child-component>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          ChildComponent,
        },
      };
      </script>
      
  5. Vue 3.0 Non-Prop Attributes and Data Binding:

    • Non-prop attributes can be used in data binding within the template.

    • They are automatically available in the template without the need for declaration in the props option.

    • Example code:

      <!-- ChildComponent.vue -->
      <template>
        <div>{{ nonPropAttribute }} - {{ computedValue }}</div>
      </template>
      
      <script>
      export default {
        computed: {
          computedValue() {
            return this.nonPropAttribute.toUpperCase();
          },
        },
      };
      </script>
      
      <!-- ParentComponent.vue -->
      <template>
        <child-component non-prop-attribute="value"></child-component>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          ChildComponent,
        },
      };
      </script>
      
  6. Using Non-Prop Attributes in Vue 3.0 Templates:

    • Non-prop attributes can be used directly in the template without the need for binding.

    • They are automatically available in the template.

    • Example code:

      <!-- ChildComponent.vue -->
      <template>
        <div>{{ nonPropAttribute }}</div>
      </template>
      
      <script>
      export default {
        props: ['nonPropAttribute'],
      };
      </script>
      
      <!-- ParentComponent.vue -->
      <template>
        <child-component non-prop-attribute="value"></child-component>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          ChildComponent,
        },
      };
      </script>
      
  7. Vue 3.0 v-bind="$attrs" for Non-Prop Attributes:

    • The v-bind="$attrs" directive allows you to bind all non-prop attributes to an element within the component.

    • This is useful when you want to pass down all non-prop attributes to a child component.

    • Example code:

      <!-- ParentComponent.vue -->
      <template>
        <child-component custom-attribute="value" v-bind="$attrs"></child-component>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          ChildComponent,
        },
      };
      </script>
      
      <!-- ChildComponent.vue -->
      <template>
        <div v-bind="$attrs">Child Component</div>
      </template>
      
      <script>
      export default {
        inheritAttrs: false,
      };
      </script>
      
  8. Custom Component Slots and Non-Prop Attributes in Vue 3.0:

    • Non-prop attributes can be used within custom component slots as well.

    • They are automatically available in the slot content.

    • Example code:

      <!-- ParentComponent.vue -->
      <template>
        <child-component>
          <template #default="{ nonPropAttribute }">
            Slot Content: {{ nonPropAttribute }}
          </template>
        </child-component>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          ChildComponent,
        },
      };
      </script>
      
      <!-- ChildComponent.vue -->
      <template>
        <div>
          <slot :nonPropAttribute="nonPropAttribute"></slot>
        </div>
      </template>
      
      <script>
      export default {
        data() {
          return {
            nonPropAttribute: 'Default Value',
          };
        },
      };
      </script>
      
  9. Vue 3.0 Non-Prop Attributes and Event Handling:

    • Non-prop attributes can be used in event handling within the template.

    • They can trigger methods or emit custom events.

    • Example code:

      <!-- ChildComponent.vue -->
      <template>
        <button @click="handleClick">{{ nonPropAttribute }}</button>
      </template>
      
      <script>
      export default {
        props: ['nonPropAttribute'],
        methods: {
          handleClick() {
            this.$emit('custom-event', this.nonPropAttribute);
          },
        },
      };
      </script>
      
      <!-- ParentComponent.vue -->
      <template>
        <child-component non-prop-attribute="Click me" @custom-event="handleCustomEvent"></child-component>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          ChildComponent,
        },
        methods: {
          handleCustomEvent(data) {
            console.log('Received data:', data);
          },
        },
      };
      </script>
      
  10. Vue 3.0 Handling Unknown Non-Prop Attributes:

    • The v-on="$listeners" directive allows you to bind all listeners (event handlers) to an element within the component.

    • This is useful when you want to pass down all event handlers to a child component.

    • Example code:

      <!-- ParentComponent.vue -->
      <template>
        <child-component @custom-event="handleCustomEvent" v-on="$listeners"></child-component>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          ChildComponent,
        },
        methods: {
          handleCustomEvent(data) {
            console.log('Received data:', data);
          },
        },
      };
      </script>
      
      <!-- ChildComponent.vue -->
      <template>
        <div v-on="$listeners">Child Component</div>
      </template>
      
      <script>
      export default {
        inheritAttrs: false,
      };
      </script>
      
  11. Vue 3.0 Non-Prop Attributes and Validation:

    • Vue 3.0 does not automatically validate non-prop attributes.

    • It's the responsibility of the component to handle and validate non-prop attributes if needed.

    • Example code:

      <!-- ChildComponent.vue -->
      <template>
        <div>{{ validatedAttribute }}</div>
      </template>
      
      <script>
      export default {
        props: ['validatedAttribute'],
        watch: {
          validatedAttribute(newValue) {
            // Custom validation logic
            if (newValue.length < 5) {
              console.error('Validation failed: Attribute should have a minimum length of 5.');
            }
          },
        },
      };
      </script>
      
      <!-- ParentComponent.vue -->
      <template>
        <child-component :validated-attribute="parentAttribute"></child-component>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          ChildComponent,
        },
        data() {
          return {
            parentAttribute: 'Short',
          };
        },
      };
      </script>
      
  12. Vue 3.0 Passing Down Non-Prop Attributes:

    • Non-prop attributes can be passed down to child components using v-bind="$attrs".

    • This is useful when you want to forward non-prop attributes to a child component.

    • Example code:

      <!-- ParentComponent.vue -->
      <template>
        <child-component v-bind="$attrs"></child-component>
      </template>
      
      <script>
      import ChildComponent from './ChildComponent.vue';
      
      export default {
        components: {
          ChildComponent,
        },
      };
      </script>
      
      <!-- ChildComponent.vue -->
      <template>
        <div v-bind="$attrs">Child Component</div>
      </template>
      
      <script>
      export default {
        inheritAttrs: false,
      };
      </script>