Building a Counter App with the Mediator Pattern in Vue 3

Building a Counter App with the Mediator Pattern in Vue 3

A Comprehensive Guide

·

3 min read

Introduction

In the world of web development, managing state effectively is crucial for building dynamic and responsive applications. Vue 3, with its powerful Composition API, offers developers a range of options for state management. While many turn to libraries like Pinia, an alternative approach is the Mediator pattern. In this article, we’ll explore the Mediator pattern, implement a counter app using this pattern in Vue 3, and compare it with Pinia to help you make an informed decision for your next project.

Understanding the Mediator Pattern

The Mediator pattern is a behavioral design pattern that promotes loose coupling between components or classes by providing a centralized mediator. This mediator is responsible for controlling and coordinating the interactions between different components. In the context of a Vue application, the Mediator acts as a central hub for state and logic, reducing the dependencies between components.

Key Benefits

  • Decoupling: Components interact with the Mediator instead of directly communicating with each other, promoting cleaner, more maintainable code.

  • Centralization: It centralizes the application logic and state management, making it easier to maintain and scale.

Implementing the Mediator Pattern in Vue 3 with Composition API

Vue 3’s Composition API is a perfect match for implementing the Mediator pattern. It allows for a more organized and modular approach to composing component logic.

Building a Counter App

Step 1: Setting Up the Mediator

First, we create a Mediator class to manage our counter's state.

Step 2: Integrating with Vue Components

We then create Vue components that interact with the Mediator.

// HomeView.vue
<script setup>
import { ref, onMounted, onUnmounted, computed, watch } from "vue";
import { mediator } from "../stores/mediator";

const count = ref(mediator.getState().count);

const updateState = (state) => {
  count.value = state.count;
};

const oddOrEven = computed(() => mediator.oddOrEven());

watch(count, (newValue) => {
  mediator.updateState({ count: newValue });
});

onMounted(() => {
  mediator.subscribe(updateState);
});

onUnmounted(() => {
  mediator.unsubscribe(updateState);
});
</script>
<template>
  <div>
    <h1>Counter</h1>
    <div class="count">{{ count }}</div>
    <div class="button-container">
      <button @click="mediator.divide">/2</button>
      <button @click="mediator.decrement">-</button>
      <button @click="mediator.increment">+</button>
      <button @click="mediator.double">*2</button>
    </div>
    <br />
    <hr />
    <br />
    <p>The number is: {{ oddOrEven }}</p>
    <br />
    <input v-model="count" type="number" id="number" />
  </div>
</template>
// Count.vue
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import { mediator } from "../stores/mediator";

const count = ref(mediator.getState().count);

const updateState = (state) => {
  count.value = state.count;
};

onMounted(() => {
  mediator.subscribe(updateState);
});

onUnmounted(() => {
  mediator.unsubscribe(updateState);
});
</script>
<template>
  <div class="about">
    <h1>This is Count Page</h1>
    <div class="counter">Count: {{ count }}</div>
  </div>
</template>

Pros and Cons in Vue 3

  • Pros: Offers more control, potentially simpler for small apps.

  • Cons: Requires more boilerplate, may become complex for large apps.

Comparing Mediator and Pinia

Pinia: The Standard State Manager

Pinia is the official state management library for Vue. It’s straightforward, integrates seamlessly with Vue’s reactivity system, and provides built-in dev tools support.

Mediator vs. Pinia: A Detailed Comparison

  • Complexity: Pinia is simpler to set up and use, while the Mediator pattern requires more manual work but offers more control.

  • Scalability: Pinia scales well for large applications. The Mediator pattern can be scalable but needs careful design.

  • Reactivity: Pinia is optimized for Vue’s reactivity system. The Mediator pattern leverages Vue’s reactivity but requires explicit handling.

  • Use Case Suitability: Pinia is great for most applications, especially large ones. The Mediator pattern shines in applications where you need tight control over state management or have specific architectural requirements.

Conclusion

The choice between the Mediator pattern and Pinia depends on your project’s needs. For applications requiring fine-grained control over state interactions, the Mediator pattern offers flexibility and direct management. However, for most Vue applications, Pinia provides an easier, more streamlined approach. By understanding both, you can choose the best tool for your Vue 3 project, ensuring efficient and effective state management.