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 install @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.