Component Composition

Composing fine-grained components in a larger component enables you to build more interesting components and applications.

Let's see how we can fit components together. We will first create a few simple components: c:helloHTML and c:helloAttributes. Then, we’ll create a wrapper component, c:nestedComponents, that contains the simple components.

Here is the source for helloHTML.cmp.

<!--c:helloHTML-->
<aura:component>
  <div class="white">
    Hello, HTML!
  </div>
  
  <h2>Check out the style in this list.</h2>
  
  <ul>
    <li class="red">I'm red.</li>
    <li class="blue">I'm blue.</li>
    <li class="green">I'm green.</li>
  </ul>
</aura:component>

CSS source

.THIS {
    background-color: grey;
}

.THIS.white {
    background-color: white;
}

.THIS .red {
    background-color: red;
}

.THIS .blue {
    background-color: blue;
}

.THIS .green {
    background-color: green;
}

Output

helloHTML output

Here is the source for helloAttributes.cmp.

<!--c:helloAttributes-->
<aura:component>
    <aura:attribute name="whom" type="String" default="world"/>
    Hello {!v.whom}!
</aura:component>

nestedComponents.cmp uses composition to include other components in its markup.

<!--c:nestedComponents-->
<aura:component>
    Observe!  Components within components!

    <c:helloHTML/>

    <c:helloAttributes whom="component composition"/>
</aura:component>

Output

nestedComponent output

Including an existing component is similar to including an HTML tag. Reference the component by its "descriptor", which is of the form namespace:component. nestedComponents.cmp references the helloHTML.cmp component, which lives in the c namespace. Hence, its descriptor is c:helloHTML.

Note how nestedComponents.cmp also references c:helloAttributes. Just like adding attributes to an HTML tag, you can set attribute values in a component as part of the component tag. nestedComponents.cmp sets the whom attribute of helloAttributes.cmp to "component composition".

Attribute Passing

You can also pass attributes to nested components. nestedComponents2.cmp is similar to nestedComponents.cmp, except that it includes an extra passthrough attribute. This value is passed through as the attribute value for c:helloAttributes.

<!--c:nestedComponents2-->
<aura:component>
    <aura:attribute name="passthrough" type="String" default="passed attribute"/>
    Observe!  Components within components!

    <c:helloHTML/>

    <c:helloAttributes whom="{#v.passthrough}"/>
</aura:component>

Output

nestedComponents2 output

helloAttributes is now using the passed through attribute value.

Note

Note

{#v.passthrough} is an unbound expression. This means that any change to the value of the whom attribute in c:helloAttributes doesn’t propagate back to affect the value of the passthrough attribute in c:nestedComponents2. For more information, see Data Binding Between Components.

Definitions versus Instances

In object-oriented programming, there’s a difference between a class and an instance of that class. Components have a similar concept. When you create a .cmp resource, you are providing the definition (class) of that component. When you put a component tag in a .cmp , you are creating a reference to (instance of) that component.

It shouldn't be surprising that we can add multiple instances of the same component with different attributes. nestedComponents3.cmp adds another instance of c:helloAttributes with a different attribute value. The two instances of the c:helloAttributes component have different values for their whom attribute .

<!--c:nestedComponents3-->
<aura:component>
    <aura:attribute name="passthrough" type="String" default="passed attribute"/>
    Observe!  Components within components!

    <c:helloHTML/>

    <c:helloAttributes whom="{#v.passthrough}"/>

    <c:helloAttributes whom="separate instance"/>
</aura:component>

Output

nestedComponent3 output