shoelace/docs/pages/frameworks/vue.md

3.9 KiB

meta
title description
Vue Tips for using Shoelace in your Vue 3 app.

Vue

Vue plays nice with custom elements, so you can use Shoelace in your Vue apps with ease.

:::tip These instructions are for Vue 3 and above. If you're using Vue 2, please see the Vue 2 instructions. :::

Installation

To add Shoelace to your Vue app, install the package from npm.

npm install @shoelace-style/shoelace

Next, include a theme and set the base path for icons and other assets. In this example, we'll import the light theme and use the CDN as a base path.

import '@shoelace-style/shoelace/dist/themes/light.css';
import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path';

setBasePath('https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/');

:::tip If you'd rather not use the CDN for assets, you can create a build task that copies node_modules/@shoelace-style/shoelace/dist/assets into a public folder in your app. Then you can point the base path to that folder instead. :::

Configuration

You'll need to tell Vue to ignore Shoelace components. This is pretty easy because they all start with sl-.

import { fileURLToPath, URL } from 'url';

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          isCustomElement: tag => tag.startsWith('sl-')
        }
      }
    })
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
});

Now you can start using Shoelace components in your app!

Usage

QR code generator example

<template>
  <div class="container">
    <h1>QR code generator</h1>

    <sl-input maxlength="255" clearable label="Value" v-model="qrCode"></sl-input>

    <sl-qr-code :value="qrCode"></sl-qr-code>
  </div>
</template>

<script setup>
  import { ref } from 'vue';
  import '@shoelace-style/shoelace/dist/components/qr-code/qr-code.js';
  import '@shoelace-style/shoelace/dist/components/input/input.js';

  const qrCode = ref();
</script>

<style>
  .container {
    max-width: 400px;
    margin: 0 auto;
  }

  sl-input {
    margin: var(--sl-spacing-large) 0;
  }
</style>

Binding Complex Data

When binding complex data such as objects and arrays, use the .prop modifier to make Vue bind them as a property instead of an attribute.

<sl-color-picker :swatches.prop="mySwatches" />

Two-way Binding

One caveat is there's currently no support for v-model on custom elements, but you can still achieve two-way binding manually.

<!-- This doesn't work -->
<sl-input v-model="name"></sl-input>
<!-- This works, but it's a bit longer -->
<sl-input :value="name" @input="name = $event.target.value"></sl-input>

If that's too verbose for your liking, you can use a custom directive instead. This utility adds a custom directive that will work just like v-model but for Shoelace components.

:::tip Are you using Shoelace with Vue? Help us improve this page! :::

Slots

To use Shoelace components with slots, follow the Vue documentation on using slots with custom elements.

Here is an example:

<sl-drawer label="Drawer" placement="start" class="drawer-placement-start" :open="drawerIsOpen">
  This drawer slides in from the start.
  <div slot="footer">
    <sl-button variant="primary" @click=" drawerIsOpen = false">Close</sl-button>
  </div>
</sl-drawer>