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.
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.
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.
There is no additional setup required, just install the library, and you are ready to go!
Add the NPM package to your repository:
npm install @vonage/vivid-vue
yarn add @vonage/vivid-vue
pnpm add @vonage/vivid-vue
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/>',
});
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>
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" />
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>
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>
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>
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>
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.
You can find examples for each component in the Vivid Vue Examples Library.