Using widgets with Vue
In this tutorial, you'll learn how to easily integrate widgets into Vue, using the WatchList widget as an example. Let's create a simple widget component.
Simple widget
Let's create a component of watch list widget as basic example:
<script setup>
import { newWatchListWidget } from '@dxfeed-widgets/watch-list'
import { onMounted, onUnmounted, ref, watchEffect } from 'vue'
const dataProviders = {
ipfPath: '/your-path/ipf',
ipfAuthHeader: 'your-header',
feedPath: 'wss://your-path/feed',
feedAuthHeader: 'your-header',
fundamentalsPath: '/api/fundamentals',
fundamentalsAuthHeader: 'your-header',
schedulePath: '/api/schedule',
}
const element = ref()
let widget
onMounted(() => {
widget = newWatchListWidget({
element: element.value,
providers: dataProviders,
config: { dataExportEnabled: true }
state: {
symbols: [],
selectedSymbol: undefined,
columns: ['symbol', 'lastPrice'],
columnSizes: {},
filters: {},
sort: undefined,
}
})
})
onUnmounted(() => {
widget?.unmount()
})
</script>
<template>
<div ref="element" style="height: 100%; width: 100%" />
</template>
Connecting widgets
Using standalone widget is a possible way to use library, but let's make something more complex and create a connection between two widgets.
Firstly, we need to establish a shareable state. As an example, we can connect widgets by symbol. In this case, our app will appear as follows:
<script setup>
import { ref } from 'vue'
import WatchList from './WatchList.vue'
const selectedSymbol$ = ref(undefined)
function onSelectedSymbol(value) {
selectedSymbol$.value = value
}
</script>
<template>
<WatchList @selected-symbol="onSelectedSymbol" />
</template>
We provide some state on the top level of our application. Let's now adjust our simple component and create one more widget to facilitate the passing of widget state.
<!-- WatchList.vue -->
<script setup>
import { newWatchListWidget } from '@dxfeed-widgets/watch-list'
import { defineEmits, onMounted, onUnmounted, ref } from 'vue'
import { dataProviders } from './dataProviders'
const emit = defineEmits<{
selectedSymbol: [string | undefined]
}>()
onMounted(() => {
widget = newWatchListWidget({
element: element.value,
providers: dataProviders,
config: { dataExportEnabled: true }
state: {
symbols: [],
selectedSymbol: undefined,
columns: ['symbol', 'lastPrice'],
columnSizes: {},
filters: {},
sort: undefined,
}
})
widget.addStateListener('selectedSymbol', symbol => {
emit('selectedSymbol', symbol)
})
})
onUnmounted(() => {
widget?.unmount()
})
</script>
<template>
<div ref="element" style="height: 100%; width: 100%" />
</template>
<!-- TimeAndSales.vue -->
<script setup>
import { newTimeAndSalesWidget } from '@dxfeed-widgets/time-and-sales'
import { defineProps, onMounted, onUnmounted, ref, toRefs, watchEffect } from 'vue'
import { dataProviders } from './dataProviders'
const props = defineProps<{
symbol: string | undefined
}>()
const props$ = toRefs(props)
onMounted(() => {
widget = newTimeAndSalesWidget({
element: element.value,
providers: dataProviders,
state: {
symbol: props$.symbol
}
})
})
watchEffect(() => {
const symbol = props$.symbol
widget?.updateState({ symbol })
})
onUnmounted(() => {
widget?.unmount()
})
</script>
<template>
<div ref="element" style="height: 100%; width: 100%" />
</template>
Now we can provide this data to another component or widget the following way:
<script setup>
import { ref } from 'vue'
import WatchList from './WatchList.vue'
import TimeAndSales from './TimeAndSales.vue'
import AnyAnotherComponent from './AnyAnotherComponent.vue'
const selectedSymbol$ = ref(undefined)
function onSelectedSymbol(value) {
selectedSymbol$.value = value
}
</script>
<template>
<WatchList @selected-symbol="onSelectedSymbol" />
<TimeAndSales :symbol="selectedSymbol$" />
<AnyAnotherComponent :symbol="selectedSymbol$" />
</template>