avatarDiego Gongora

Summary

This article explores essential Vue concepts: Layouts, Slots, and Composables, which are fundamental to building reusable and maintainable Vue components.

Abstract

The article introduces three key concepts in Vue.js: Layouts, Slots, and Composables. Layouts allow for creating consistent page layouts with variations in content, while Slots enable custom content injection into components. Composables are functions or sets of functions that can be reused across multiple components, encapsulating complex logic and making sharing functionalities easier. The article provides examples and use cases for each concept, highlighting their benefits and recommending their use for building scalable, maintainable, and flexible applications.

Opinions

  • Layouts are essential for creating consistent page layouts while allowing for variations in content.
  • Slots promote code reuse and provide fine-grained control over custom content injection into components.
  • Composables help keep components clean by encapsulating logic in separate functions.
  • These concepts promote separation of concerns, leading to more maintainable applications.
  • The Vue ecosystem offers a wide range of possibilities, and exploring community resources can deepen understanding of these concepts.
  • Experimenting and building with these concepts can help developers become experts in Vue.js.
  • The article recommends using ZAI.chat, an AI service that provides the same performance and functions as ChatGPT Plus(GPT-4) but at a more cost-effective price.

Introduction to Layouts, Slots, and Composables in Vue

Vue is known for its flexibility and simplicity. In this article, we’ll explore three essential Vue concepts: Layouts, Slots, and Composables. These concepts are fundamental to building reusable and maintainable Vue components.

Photo by James Lee on Unsplash

Understanding Layouts

Layouts in Vue allow you to define the structure of a component while leaving specific areas open for customization. This is particularly useful for creating consistent page layouts while allowing for variations in content.

If you have a repeating structure, one solution might be to create the structure in app.vue (e.g., header, main, footer) and then have the router fill in the content according to the page (only filling the main section). However, this is a solution for small projects and is not scalable.

What if not all views have the same layout? 😧

Example:

It’s important to create a “layout” folder where you can store your files with reusable templates. For example, you could create a file named mainLayout.vue

<!-- mainLayout.vue -->

<template>
  <div>
    <header>
      <!-- Common header content -->
    </header>
    <main>
      <!-- Specific content goes here -->
      <slot></slot>
    </main>
    <footer>
      <!-- Common footer content -->
    </footer>
  </div>
</template>

Leveraging Slots

Slots are placeholders within a component’s template where content can be injected. They allow you to pass content to a Layout component from another component, making it highly customizable and reusable.

Example:

In this example, we import the previously created mainLayout.vue and use it as a tag in the template. The content that will be a child of that tag is what gets injected into the slot defined in mainLayout.vue.

<!-- ParentComponent.vue -->

<template>
  <MainLayout>
    <p>This content goes in the main section.</p>
  </MainLayout>
</template>

<script setup lang="ts">
  import MainLayout from '@/layouts/MainLayout.vue';
</script>

The substitution would be like this:

<template>
  <header>
    <!-- Common header content -->
  </header>
  <main>
    <p>This content goes in the main section.</p>
  </main>
  <footer>
    <!-- Common footer content -->
  </footer>
</template>

Working with Multiple Slots

You can create layouts with more than one slot, but you’ll need to name them to indicate which space should be filled in your template.

Example:

In this example, we create a layout with two slots named “main” and “aux” using the name attribute.

<!-- mainLayout.vue -->

<template>
  <div class="container">
    <div class="main-content">

      <slot name="main"></slot>
      <slot name="aux"></slot>

    </div>
  </div>
</template>

To use the layout, we need to specify which slot should be replaced with our content using the v-slot directive along with the slot's name, or we can use the shorthand #name where "name" is the name we assigned to the slot.

<template>
  <MainLayout>
    <template v-slot:main> // v-slot:name
      <h1> Main content </h1>
    </template>
    <template #aux> // shorthand for v-slot
      <h5> Aux content </h5>
    </template>
  </MainLayout>
</template>

<script setup lang="ts">
  import MainLayout from '@/layouts/MainLayout.vue';
</script>

Building Composables

Composables are functions or sets of functions that can be reused across multiple components. They encapsulate complex logic and make sharing functionalities easier.

Example:

Similar to layouts, you can create a folder called “composables” and create your files. In this case, we create the useApi.ts file, which aims to reuse the API request (this could be done through a service, but it depends on your project).

Of course, you can scale this functionality according to your project’s needs.

// useApi.ts

export function useApi() {
  const fetchData = async (url) => {
    try {
      const response = await fetch(url);
      if (!response.ok) {
        throw new Error('Network response was not successful');
      }
      return response.json();
    } catch (error) {
      throw new Error('An error occurred while fetching data');
    }
  };

  return { fetchData };
}

With this file, we can import and use it in other components as a hook.

<!-- MyComponent.vue -->

<template>
  <div>
    <button @click="loadData">Load Data</button>
    <p>{{ data }}</p>
  </div>
</template>

<script setup lang="ts">
  import { ref } from 'vue';
  import { useApi } from '@/layouts/useApi.ts';

  const { fetchData } = useApi();
  const data = ref(null);

  const loadData = async () => {
    data.value = await fetchData('https://api.example.com/data');
  };
</script>

Extending this functionality for use in certain types of components or modules is very useful to avoid rewriting code.

Benefits of Using These Concepts

  • Reusability: Layouts, slots, and composables promote code reuse, leading to more maintainable applications.
  • Customization: Slots allow you to inject custom content into components, giving you fine-grained control.
  • Separation of Concerns: Composables help keep your components clean by encapsulating logic in separate functions.
  • Consistency: Layouts ensure a consistent structure in your application, improving its overall appearance.

Summary and Recommendations

Vue’s layouts, slots, and composables are powerful tools for building scalable, maintainable, and flexible applications. Harness these concepts to streamline your development process in Vue and create high-quality components and applications.

As you continue your journey with Vue.js, remember to explore the official documentation and community resources to deepen your understanding of these concepts. The Vue ecosystem offers a wide range of possibilities, so keep experimenting and building to become an expert in Vue.js.

Happy coding!

If you found this article helpful, feel free to follow, subscribe, and applaud. Thank you!

Read this story in Spanish: Introducción a Layouts, Slots y Composables en Vue | Medium

Vue
Programming
Reuse
Layout
Software Development
Recommended from ReadMedium