Vivid Logo Vivid

Getting Started With Vue

Vivid comes with a library of native Vue components that wrap the Vivid web components, called Vivid Vue.

While web components can also be used with Vue directly, Vivid Vue provides a seamless integration with Vue and reduces the amount of boilerplate required.

Features

Native Bindings

  • Vivid Vue components can be imported and used like any other Vue component, including features like v-model and slots.
  • It comes with full type definitions providing type safety and auto-complete in your IDE.

Complete and Up-To-Date

  • Vivid Vue is generated from the Vivid web components automatically, so it is always up-to-date with the latest version of Vivid.
  • The version number is kept in sync with Vivid.

Supports Vue 2 & Vue 3

  • There is no additional setup required, just install the library, and you are ready to go!

Installation

Add the NPM package to your repository:

npm install @vonage/vivid-vue
yarn add @vonage/vivid-vue
pnpm install @vonage/vivid-vue

Setup

Use the vivid3 plugin to initialize the library.

// main.ts
import { createApp } from 'vue';
import { vivid3 } from '@vonage/vivid-vue';
import App from './App.vue';

createApp(App)
	.use(vivid3, {
		font: 'spezia',
		customComponentPrefix: 'my-app',
	})
	.mount('#app');

The plugin accepts the following options:

Option Type Default Description
tokens 'light | 'dark' | 'none' 'light' The theme of tokens to use.
font 'oss' | 'spezia' | 'none' 'oss' Use 'spezia' to load the Vonage-specific Spezia font.
customComponentPrefix string 'vvd3' The prefix to use for custom components. It is recommended to set a prefix unique to your app to prevent conflicts if multiple instances or versions of Vivid are used in the same page. Learn more about custom prefixes.
styles Style[] [] An array of optional styles to use.
addRootClassTo 'root' | 'app' | 'none' 'root' Where to apply the vvd-root class to.
- root: The <html> element
- app: The App component

Loading Optional Styles

To load optional styles, pass them to the styles option.

See the list of styles that come with Vivid for more information.

// main.ts
import { createApp } from 'vue';
import { optionalStyles, vivid3 } from '@vonage/vivid-vue';
import App from './App.vue';

createApp(App)
	.use(vivid3, {
		styles: [
			optionalStyles.theme,
			optionalStyles.typography,
			optionalStyles.vivid2Compat,
		],
	})
	.mount('#app');

Adding the vvd-root Class

The Vivid tokens require a vvd-root class to be present. It is recommended to add it on the <html> element, but it can also be added to your App component to scope it to the application.

<!-- index.html -->
<!DOCTYPE html>
<html lang="en" class="vvd-root">
	<!-- ... -->
</html>
<!-- App.vue -->
<template>
	<div class="vvd-root">
		<RouterView />
	</div>
</template>

Importing the Styles

Modify your App.vue file to import the Vivid styles.

See the list of styles that come with Vivid for more information.

<!-- App.vue -->
<template>
	<RouterView />
</template>

<style>
	/* Import Tokens For Light or Dark Theme */
	@import '@vonage/vivid/styles/tokens/theme-light.css';
	/* (Vonage only) Load Spezia Variable fonts */
	@import '@vonage/vivid/styles/fonts/spezia-variable.css';
	/* (Optional) Import Theme Styles */
	@import '@vonage/vivid/styles/core/theme.css';
	/* (Optional) Import Typography Styles */
	@import '@vonage/vivid/styles/core/typography.css';
	/* (Optional) Import Vivid 2 Compatibility Styles */
	@import '@vonage/vivid/styles/tokens/vivid-2-compat.css';
</style>
<!-- App.vue -->
<template>
	<RouterView />
</template>

<style lang="scss">
	/* Import Tokens For Light or Dark Theme */
	@forward '@vonage/vivid/styles/tokens/theme-light.css';
	/* (Vonage only) Load Spezia Variable fonts */
	@forward '@vonage/vivid/styles/fonts/spezia-variable.css';
	/* (Optional) Import Theme Styles */
	@forward '@vonage/vivid/styles/core/theme.css';
	/* (Optional) Import Typography Styles */
	@forward '@vonage/vivid/styles/core/typography.css';
	/* (Optional) Import Vivid 2 Compatibility Styles */
	@forward '@vonage/vivid/styles/tokens/vivid-2-compat.css';
</style>

Vonage uses the brand-specific Spezia font.

If you are not working on a Vonage project, you should use the Montserrat and Roboto Mono fonts.

Add the following to your <head> to load them from Google Fonts:

<head>
	<!-- ... -->
	<link rel="preconnect" href="https://fonts.googleapis.com" />
	<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
	<link
		href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600&family=Roboto+Mono:wght@400;500&display=swap"
		rel="stylesheet"
	/>
	<!-- ... -->
</head>

Setting Custom Component Prefix (optional)

It is recommended to set a custom component prefix unique to your app. This will prevent conflicts if multiple instances or versions of Vivid are used in the same page.

To set a custom component prefix, use the setCustomComponentPrefix function in your main.ts file.

// main.ts
import Vue from 'vue';
import { setCustomComponentPrefix } from '@vonage/vivid-vue';
import App from './App.vue';

// set custom component prefix for the whole application (e.g. fraud-detection, etc.)
setCustomComponentPrefix('my-app');

new Vue({
	el: '#app',
	components: { App },
	template: '<App/>',
});

Usage

You are now ready to use the components in your application.

<script setup lang="ts">
	import { VButton } from '@vonage/vivid-vue';
</script>

<template>
	<VButton label="Click me" />
</template>

Using v-model

The v-model syntax allows us to implement a two-way binding in between a variable and the matching component.

This is an example of a two-way binding implementation for a web component:

<vwc-text-field
	label="Search"
	:value="searchText"
	@input="searchText = $event.target.value"
/>

This works fine, but with Vivid Vue we can use the v-model syntax to shorten this to:

<VTextField label="Search" v-model="searchText" />

Default Slots

The default slot maps to the same syntax in both Vivid Vue & web components.

Web component

<vwc-icon size="3">
	<img src="/custom-logo.svg" />
</vwc-icon>

Vivid Vue

<VIcon size="3">
	<img src="/custom-logo.svg" />
</VIcon>

Named Slots

While the default slots work the same, the web component's named slots are mapped to Vue named slots.

Web component

<vwc-banner text="A banner with an action button">
	<vwc-button
		slot="action-items"
		appearance="filled"
		connotation="accent"
		label="Filled"
	/>
	<vwc-button
		slot="action-items"
		appearance="outlined"
		connotation="accent"
		label="Outlined"
	/>
</vwc-banner>

Vivid Vue

<VBanner text="A banner with an action button">
	<template #action-items>
		<VButton appearance="filled" connotation="accent" label="Filled" />
		<VButton appearance="outlined" connotation="accent" label="Outlined" />
	</template>
</VBanner>

Styling Components

Components can be styled like any other Vue components, e.g. by using class or id attributes.

Although possible, avoid targeting the custom elements directly by their name (e.g. vwc-header), as you might need to change the prefix in the future.

<template>
	<VHeader class="header">Header Content</VHeader>
</template>
<style scoped lang="css">
	.header {
		margin-block-end: 12px;
		--header-bg-color: var(--vvd-color-neutral-200);
	}
	.header::part(base) {
		position: fixed;
	}
</style>

Client-Side Navigation

Components like VNavItem, VBreadcrumbItem or VButton become links when using the href prop.

They will render a regular <a> tag and therefore navigate to the specified URL with a full page reload.

If you are using Vue Router and want to perform client-side navigation, wrap the component with RouterLink:

<RouterLink v-slot="{ href, navigate }" to="/page" custom>
	<VButton :href="href" label="Page" @click="navigate" />
</RouterLink>

Auto-Complete

Vivid Vue supports auto-complete for components, props, slots, events and more in popular IDEs.

  • IntelliJ IDEs (WebStorm, PhpStorm, etc.): Supported out of the box.
  • VSCode: Install the Volar extension.

Examples

You can find examples for each component in the Vivid Vue Examples Library.