0.2.1 • Published 8 months ago

@medusa-v2-vue/core v0.2.1

Weekly downloads
-
License
MIT
Repository
-
Last release
8 months ago

Medusa V2 Vue

Vue 3 composables and components for seamless and streamlined interaction with a Medusa.

If you're building a custom vue based storefront that consumes a medusa backend and find yourself wishing you had something nice at hands like medusa-react to streamline your data management - this might be your library!

Installation

The library uses @tanstack/vue-query under the hood.

For the core composables run:

npm install @medusa-v2-vue/core
# or
yarn add @medusa-v2-vue/core

For the components (WIP :construction_worker:):

npm install @medusa-v2-vue/components
# or
yarn add @medusa-v2-vue/components

Quick Start

In order to use the composables exposed by this library you need to register it as a plugin in your main file before mounting your app. The plugin takes a config object that needs at least a baseUrl where it can reach your server. Optionally, it allows you to pass additional props to configure both the underlying medusa-js and the vue-query client. Here's the complete interface. Refer to these and these docs, respectively to get an idea on how the parts work together.

interface MedusaVueClientProps {
  baseUrl: string;
  maxRetries?: number;
  /**
   * Authentication token
   */
  apiKey?: string;
  /**
   * PublishableApiKey identifier that defines the scope of resources
   * available within the request
   */
  publishableApiKey?: string;

  queryClientProviderProps?: VueQueryPluginOptions;
}

Plug it in:

// main.ts
import { createApp } from 'vue';
import App from './App.vue';

import { createMedusaVueClient } from '@medusa-v2-vue/core';

const client = createMedusaVueClient({
  baseUrl: '<YOUR_SERVER_BASE_URL>',
});

const app = createApp(App);

app.use(client).mount('#app');

The hooks exposed by medusa-v2-vue fall into two main categories: queries and mutations.

Queries

Queries simply wrap around vue-query's useQuery hook to fetch some data from your medusa server

// ./my-product-list.vue
<script setup lang="ts">
import { watch } from 'vue';
import HelloWorld from './components/HelloWorld.vue';
import { useProducts } from '@medusa-v2-vue/core';

const { data, error, isLoading } = useProducts();
</script>

<template>
  <ul v-for="products in data?.products">
    <li>...</li>
  </ul>
</template>

Note: If you've worked with @medusajs/medusa-react you might be used to being able to destructure the recordset returned by the server, i.e. const { products } = useProducts(). This is however not possible with vue due to the way it's reactive system works.

Mutations

Mutations wrap around vue-query's useMutation to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of "mutations", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a mutate() function returned from mutation hooks.

<script setup lang="ts">
import { useCreateCart } from '@medusa-v2-vue/core';

const createCart = useCreateCart();
const handleClick = () => {
  createCart.mutate({}); // create an empty cart
};
</script>

<template>
  <Button isLoading="{createCart.isLoading}" onClick="{handleClick}">
    Create cart
  </Button>
</template>

The mutation hooks will return exactly what vue-query's useMutation returns. In addition, the options you pass in to the hooks will be passed along to useMutation.

Components

NOTE: This is still work in progress and new components will gradually be added!:construction_worker:

If you prefer declarative templates, @medusa-v2-vue/components provided (almost) renderless components to use directly in your template and provide data through slot-props. This allows for extremely streamlinend and declarative templating:

<script setup lang="ts">
import { UseProducts } from '@medusa-v2-vue/components';
</script>

<template>
  <use-products v-slot="{ data, isLoading }">
    <loading-spinner v-if="isLoading" />

    <product-list :products="data.products" />
  </use-products>
</template>

The component also allows to pass down the laoding indicating component via a slot:

<script setup lang="ts">
import { UseProducts } from '@medusa-v2-vue/components';
</script>

<template>
  <use-products>
    <template #fallback>
      <div>Loading....</div>
    </template>

    <template v-slot="{ data, isLoading }">
      <product-list :products="data.products" />
    </template>
  </use-products>
</template>

Utilities

A set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts

formatAmount()

  • formatAmount(params: FormatAmountParams): string
type FormatAmountParams = {
  amount: number;
  region: RegionInfo;
  includeTaxes?: boolean;
  minimumFractionDigits?: number;
  maximumFractionDigits?: number;
  locale?: string;
};

Returns a localized string based on the input params representing the amount (i.e: "$10.99").

Credits

Based on and inspired by medusa-react. Keep up the good work! :beers:

0.2.1

8 months ago

0.2.0

8 months ago

0.1.4

8 months ago

0.1.3

8 months ago

0.1.2

8 months ago

0.1.1

9 months ago

0.1.0

9 months ago