Skip to content

8. project [vuejs-06]: laying out a view with slots

Image

8.1. The main script [main.js]

The main script [main.js] remains unchanged.

8.2. The main component [App]

The code for the [App] component is as follows:


<template>
  <div class="container">
    <b-card>
      <b-alert show variant="success" align="center">
        <h4>[vuejs-06]: Layout with slots</h4>
      </b-alert>
      <Content />
    </b-card>
  </div>
</template>


<script>
  import Content from './components/Content'
  export default {
    name: "app",
    // components used
    components: {
      Content
    }
  };
</script>

The [App] component introduces a new component called [Content] (lines 7, 14, 19).

8.3. The [Layout] component

The [Layout] component is used to define the layout of the application's views:


<template>
  <!-- line -->
  <b-row>
    <!-- three-column area -->
    <b-col cols="3" v-if="left">
      <slot name="slot-left" />
    </b-col>
    <!-- nine-column area -->
    <b-col cols="9" v-if="right">
      <slot name="slot-right" />
    </b-col>
  </b-row>
</template>

<script>
  export default {
    name: "pattern",
    // settings
    props: {
      left: {
        type: Boolean
      },
      right: {
        type: Boolean
      }
    }
  };
</script>

Comments

  • The [Layout] component defines a single row (lines 3–12). This row is divided into two columns:
    • a column consisting of 3 Bootstrap columns (lines 5–7);
    • a column consisting of 9 Bootstrap columns (lines 9–11);
  • line 5: the presence of the left column (lines 5–7) depends on the value of the [left] parameter, defined in the component’s [props] property (lines 20–22);
  • line 9: the presence of the right column (lines 9–11) depends on the value of the [right] parameter, defined in the component’s [props] property (lines 23–25);
  • the values of the [left, right] parameters must be set by a parent component of the [Layout] component;
  • line 6: the content of the left column is not specified. We simply give this column a name using the <slot> tag. Here, it will be called [slot-left]. A component using the [Content] component must specify what it wants to place in the area called [slot-left];
  • line 10: the right column will be called [slot-right];

8.4. The [Right] component

The [Right] component is as follows:


<template>
  <!-- a message in a warning-type alert -->
  <b-alert show variant="warning" align="center">
    <h4>{{msg}}</h4>
  </b-alert>
</template>

<!-- script -->
<script>
  export default {
    name: "right",
    // parameters
    props: {
      msg: String
    }
  };
</script>
  • lines 3–5: The [Right] component displays a message in a [warning] alert. This message [msg] is defined as a component parameter on line 14. The parent component must therefore provide it with a value;

8.5. The [Left] component

The [Left] component is as follows:


<template>
  <!-- a message in a primary-type alert -->
  <b-alert show variant="primary" align="center">
    <h4>{{msg}}</h4>
  </b-alert>
</template>

<!-- script -->
<script>
  export default {
    name: "left",
    // parameters
    props: {
      msg: String
    }
  };
</script>
  • lines 3–5: The [Left] component displays a message in a [primary] alert. This message [msg] is defined as a component parameter on line 14. The parent component must therefore provide it with a value;

8.6. The [Content] component

Recall that the [Content] component is the component displayed by the main view [App.vue]:


<template>
  <div>
    <!-- left and right columns filled -->
    <Layout :left="true" :right="true">
      <Right slot="slot-right" msg="slot [slot-right] present and filled" />
      <Left slot="slot-left" msg="slot [slot-left] present and filled" />
    </Layout>
    <!-- Left column empty. Right column filled -->
    <Layout :left="false" :right="true">
      <Right slot="slot-right" msg="slot [slot-right] present and filled, slot [slot-left] absent" />
    </Layout>
    <!-- left column filled, right column absent -->
    <Layout :left="true" :right="false">
      <Left slot="slot-left" msg="slot [slot-left] present and filled, slot [slot-right] absent" />
    </Layout>
    <!-- left column present but not filled, right column filled -->
    <Layout :left="true" :right="true">
      <Right slot="slot-right" msg="slot [slot-right] present and filled, slot [slot-left] present but empty" />
    </Layout>
  </div>
</template>

<!-- script -->
<script>
  import Layout from "./Layout";
  import Left from "./Left";
  import Right from "./Right";
  export default {
    name: "content",
    // components
    components: {
      Layout,
      Left,
      Right
    }
  };
</script>

Visual rendering

Image

Comments

  • The [Layout] component is used 4 times (lines 4–7, 9–11, 13–15, 17–19). Since the [Layout] component defines 1 row, the [template] above defines four rows. Also, the [Layout] row defines two columns:
    • a column called [slot-left] that occupies the 3 left Bootstrap columns;
    • a column called [slot-right] that occupies the 9 right Bootstrap columns;
  • Lines 4–7: defines a [1] row where the [Left] component occupies the [slot-left] column and the [Right] component occupies the [slot-right] column;
  • lines 9–11: defines a row [2] where the [slot-left] column is not displayed and the [Right] component occupies the [slot-right] column;
  • lines 13–15: defines a row [3] where the [slot-right] column is not displayed and the [Left] component occupies the [slot-left] column;
  • lines 17–19: defines a row [4] where the [slot-left] column is displayed [:left=’true’] but not filled, and the [Right] component occupies the [slot-right] column;

Ultimately, the [Layout] component served as the layout for the [Content] component.