javascript - 如何在间隔上自动切换 VueJS 选项卡
问题描述
这是我的第一个 VueJS Applicationa,它更像是一个 POC,而不是一个严肃的项目。尽管如此,我真的很想解决我的问题。
该应用程序类似于几个“组”的仪表板,每个组都有一定数量的数据,我可以可视化。对于每种类型的数据,我都有一个选项卡,在每个选项卡中,每个组都有这种可视化的数据。
所以。现在我面临的问题是,作为仪表板,它应该能够在没有用户交互的情况下显示所有信息。为了实现这一点,我需要在时间间隔上更改选项卡。因此,例如每 5 分钟显示另一个选项卡。我希望这是有道理的。
我已经在 Google 上搜索了一些解决方案,但要让它们发挥作用,我需要重写几乎所有当前的工作。因此,我正在寻找可以在当前项目中实施的解决方案。
到目前为止,这是我的代码:
仪表板.vue
<template>
<div style="margin-left:220px" class="text-center m-3">
<tabs>
<tab title="Robots">
<div v-if="responseAvailable == true">
<div v-for="customer in result" class="customerCard">
<span class="card-content">
{{ customer.CustomerName }}
<hr />
<div v-for="robot in customer.ListOfRobots" :class="robot.State">
{{ robot.Name }}
</div>
</span>
</div>
</div>
</tab>
<tab title="Jobs" :selected="true">
<div v-if="responseAvailable == true">
<div v-for="customer in result" class="customerCard">
<span class="card-content">
{{ customer.CustomerName }}
<hr />
<apexchart width="500" type="bar"
:options="customer.options" :series="customer.ListForFrontend">
</apexchart>
</span>
</div>
</div>
</tab>
<tab title="Queues">
<div v-if="responseAvailable == true">
<div v-for="customer in result" class="customerCard">
<span class="card-content">
{{ customer.CustomerName }}
<hr />
<div v-for="queue in customer.ListOfQueues" id="chart">
{{ queue.Name }}
<apexchart type="line" height="200" :options="lineChartOptions" :series="queue.FrontedListQueues"></apexchart>
</div>
</span>
</div>
</div>
</tab>
<tab title="Triggers">
<div v-if="responseAvailable == true">
<div v-for="customer in result" class="customerCardPie">
<span class="card-content">
{{ customer.CustomerName }}
<hr />
<apexchart type="pie" width="280" :options="piechartOptions" :series="customer.TriggersFE"></apexchart>
</span>
</div>
</div>
</tab>
</tabs>
</div>
</template>
<script>
import M from 'materialize-css'
import ApexCharts from 'apexcharts'
import Tab from './Tabs/Tab.vue'
import Tabs from './Tabs/Tabs.vue'
export default {
name: 'Dashboard',
components: {
Tab,
Tabs
},
/*data() {
return {
result: null,
responseAvailable: null,
timer: ""
}
},*/
data: () => ({
result: null,
responseAvailable: null,
timer: "",
pieSeries: [34,345,123,6,75],
piechartOptions: {
chart: {
width: 280,
type: 'pie',
},
labels: ['Enabled', 'Disabled'],
colors: ['#11FF00', '#FF0000',],
responsive: [{
breakpoint: 480,
options: {
chart: {
width: 200
},
legend: {
position: 'bottom'
}
}
}]
},
lineChartOptions: {
chart: {
height: 200,
type: 'line',
zoom: {
enabled: false
}
},
dataLabels: {
enabled: false
},
colors: ['#11FF00', '#FFA200', '#FF0000', ],
stroke: {
curve: 'smooth'
},
grid: {
row: {
colors: ['#f3f3f3', 'transparent'], // takes an array which will be repeated on columns
opacity: 0.5
},
},
xaxis: {
//categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'],
categories: ['01:00', '02:00', '03:00', '04:00', '05:00', '06:00', '07:00', '08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00', '00:00',],
}
},
}),
created() {
this.fetchAPIData();
this.timer = setInterval(this.fetchAPIData, 900000)
},
mounted() {
M.AutoInit(); // That way, it is only initialized when the component is mounted
},
methods: {
fetchAPIData() {
this.responseAvailable = false;
fetch("https://localhost:44378/api/values", {
"method": "GET",
})
.then(response => {
if (response.ok) {
return response.json()
} else {
alert("Server returned " + response.status + " : " + response.statusText);
}
})
.then(response => {
this.result = response;
console.log(this.result[0].ListOfQueues[1].FrontedListQueues[0].data);
this.responseAvailable = true;
})
.catch(err => {
alert(err);
});
},
cancelAutoUpdate() {
clearInterval(this.timer)
}
},
beforeDestroy() {
clearInterval(this.timer)
}
};
</script>
选项卡.vue
<template lang="html">
<div class='tab' v-show='isActive'>
<slot></slot>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: 'Tab'
},
name: { requred: true },
selected: { default: false }
},
data() {
return {
isActive: true
}
},
mounted() {
this.isActive = this.selected;
},
computed: {
href() {
return "#" + this.name.toLowerCase().replace(/ /g, '-');
}
}
}
</script>
选项卡.vue
<template lang="html">
<div>
<ul class='tabs__header'>
<li v-for='tab in tabs'
:key='tab.title'
@click='selectTab(index)'
:class='{"tab__selected": (index == selectedIndex)}'>
<a :href="tab.href" @click="selectNewTab(tab)">{{ tab.name }}</a>
</li>
</ul>
<slot></slot>
</div>
</template>
<script>
export default {
data() {
return {
selectedIndex: 0, // the index of the selected tab,
tabs: [] // all of the tabs
}
},
created() {
this.tabs = this.$children
},
mounted() {
//this.selectTab(0);
let tabsVue = this;
setInterval(function () {
tabsVue.changeToNextTab();
}, 1000);
},
methods: {
changeToNextTab() {
if (!this.tabs.length) {
return;
}
let activeIndex = this.tabs.findIndex(tab => tab.isActive);
if (activeIndex === -1) {
activeIndex = 0;
}
// add one to the index for the next tab
activeIndex++;
if (activeIndex >= this.tabs.length) {
// Reset to first tab if on the last tab
activeIndex = 0;
}
this.selectNewTab(this.tabs[activeIndex]);
},
selectNewTab(slectedTab) {
this.tabs.forEach(tab => {
tab.isActive = (tab.name == slectedTab.name)
})
}
}
}
</script>
任何帮助深表感谢。我怎么说,这是我的第一个 VueJS 项目,所以我知道有些事情不是最佳实践。
Codesandbox:https ://codesandbox.io/s/priceless-mountain-m9fl9?file=/src/main.js
解决方案
推荐阅读
- docker - 使用 chmod 安装时在 docker 中找不到命令
- reflection - 将 typeorm 实体转换为 json 模式
- google-app-engine - 我想知道在哪里以及如何部署和托管我的 Nuxt 应用程序
- css - 当 sass 文件中有 url 时,Webpack 模块构建失败
- linux - 简单的 Linux 基准测试工具
- python - 遍历 pandas 数据框中的行
- vb.net - 如何通过(选择和分组依据)从数据表中获取数据
- python - 仅在熊猫数据框中的特定时间范围之间保留行
- multithreading - 在哪里以及如何实现线程 - Kotlin
- ruby-on-rails - 创建一个 cookie 以使用法拉第 GET 请求发送