我是一个初学者。我尝试从API获取数据,并使用v-for
列出它们。但这会导致延迟。当数据到来或我在列表中搜索某些内容时,我的应用程序会冻结。这部分代码是我获取数据的地方。如何改进代码以使应用程序更流畅。
async created() {
this.loaded = false;
try {
const response = await fetch(
'https://api2.binance.com/api/v3/ticker/24hr'
);
const data = await response.json();
data.forEach(element => {
this.chartData.symbols = [...this.chartData.symbols, element.symbol];
this.chartData.price = [...this.chartData.price, +element.lastPrice];
});
this.loaded = true;
} catch (e) {
console.error(e);
}
},
我的应用程序组件:
<template>
<v-app>
<v-row align="center" class="ma-8 pa-6" fluid>
<!-- Container Start Point For buttons-->
<div class="mb-6 d-flex justify-start hidden">
<v-btn @click="toggleButton" depressed color="primary" class="mr-6 btn">
{{ (btnText = dialog ? 'Add/Update' : 'Add Stock') }}
</v-btn>
<v-btn @click="refreshPage" depressed color="primary" class="btn">
Refresh
</v-btn>
</div>
<!-- Container End Point For Buttons-->
<!-- Modal Code Starts-->
<v-dialog
v-model="dialog"
width="80%"
height="900px"
overflow="hidden"
pa-6
>
<v-card class="pa-12">
<v-form>
<v-text-field
v-model="search"
label="Search"
outlined
></v-text-field>
<v-row>
<v-list-item
v-for="(pair, index) in filterBy(pairs, search)"
:key="pair.symbol"
>
<v-list-item-content>
<v-list-item-title ref="refWord"
>{{ pair.symbol }} - {{ pair.price }}</v-list-item-title
>
</v-list-item-content>
<v-text-field
outlined
v-model="numberValue"
hide-details
single-line
type="number"
class="shrink mr-2"
width="50px"
height="50px"
/>
<AddBtn @click-event="searchHandle(index)" />
</v-list-item>
</v-row>
</v-form>
</v-card>
</v-dialog>
<!-- Modal Code Ends-->
<!-- Horizontal Line-->
<hr class="line" />
<!--Mainpage List Starts -->
<v-col cols="12" sm="5" height="1000px">
<v-container height="1000px">
<v-list-item
class="border"
v-for="(label, index) in chartData.labels"
:key="index++"
>
<v-row>
<v-list-item-content d-flex>
<v-list-item-title
>{{ label }}
<span>{{
chartData.datasets[0].data[index]
}}</span></v-list-item-title
>
</v-list-item-content>
<v-btn class="btn" dark md color="error" @click="deleteHandle">
Delete
</v-btn>
</v-row>
</v-list-item>
</v-container>
</v-col>
<!-- Mainpage List End-->
<!-- Vertical Line-->
<hr class="vertical" />
<!-- Chart part -->
<v-col cols="12" sm="5">
<PieChart
:data="this.chartData.datasets[0].data"
:bgColor="this.chartData.datasets[0].backgroundColor"
:labels="this.chartData.labels"
:key="this.chartData.labels.length"
/>
</v-col>
<!-- Chart part end-->
</v-row>
</v-app>
</template>
<script>
import PieChart from './components/PieChart';
import Vue2Filters from 'vue2-filters';
import AddBtn from './components/AddBtn.vue';
export default {
name: 'App',
mixins: [Vue2Filters.mixin],
components: {PieChart, AddBtn},
methods: {
toggleButton() {
this.dialog = !this.dialog;
// this.btnText = this.dialog ? 'Add / Update' : 'Add Stock';
},
searchHandle(index) {
const [sym, price] = this.$refs.refWord[index].innerText.split('-');
this.symbol = sym;
this.chartData.labels = [...this.chartData.labels, sym];
this.chartData.datasets[0].data = [
...this.chartData.datasets[0].data,
+price,
];
},
deleteHandle() {
this.chartData.labels.pop();
this.chartData.datasets[0].data.pop();
this.chartData.datasets[0].backgroundColor.pop();
},
refreshPage() {
setTimeout(function () {
location.reload();
}, 100);
},
},
data: () => ({
dialog: false,
search: '',
btnText: 'Add Stock',
numberValue: 1,
chartData: {
labels: ['CHM', 'BBM', 'LLJTRY'],
symbols: [],
price: [],
datasets: [
{
data: [0.035, 0.26, 0.022],
backgroundColor: [
'#41B883',
'#E46651',
'#20AB2E',
'#DD1B16',
'#DD26FF',
'#9ab973',
`#${Math.floor(Math.random() * 16777215).toString(16)}`, // Random color
],
},
],
},
}),
computed: {
pairs() {
return this.chartData.symbols.map((symbol, i) => {
return {
symbol: symbol,
price: this.chartData.price[i],
};
});
},
},
async created() {
this.loaded = false;
try {
const response = await fetch(
'https://api2.binance.com/api/v3/ticker/24hr'
);
const data = await response.json();
data.forEach(element => {
this.chartData.symbols = [...this.chartData.symbols, element.symbol];
this.chartData.price = [...this.chartData.price, +element.lastPrice];
});
this.loaded = true;
} catch (e) {
console.error(e);
}
},
};
</script>
<style scoped>
.btn {
text-transform: none !important;
}
.line {
width: 100%;
margin: 0 auto;
}
hr.vertical {
height: 80%;
margin: 3% auto;
}
.scroller {
height: 100%;
}
.border {
border: 1px solid rgba(0, 0, 0, 0.123);
padding: 5px 20px;
margin: 10px 0;
border-radius: 10px;
}
</style>
饼图组件:
<template>
<Pie
v-if="loaded && this.chartData.labels.length !== 0"
id="my-chart-id"
:options="chartOptions"
:data="chartData"
/>
<Pie v-else :options="chartOptions" :data="emptyChartData"></Pie>
</template>
<script>
import {Chart as ChartJS, ArcElement, Tooltip, Legend} from 'chart.js';
import {Pie} from 'vue-chartjs';
ChartJS.register(ArcElement, Tooltip, Legend);
export default {
name: 'PieChart',
components: {Pie},
props: ['data', 'bgColor', 'labels'],
data() {
return {
chartData: {
labels: [...this.labels],
datasets: [
{
data: [...this.data],
backgroundColor: [...this.bgColor],
},
],
},
emptyChartData: {
labels: [],
datasets: [
{
data: [0.01],
backgroundColor: ['#999797'],
},
],
},
chartOptions: {
responsive: true,
elements: {
arc: {
borderWidth: 0,
},
},
},
loaded: true,
};
},
};
</script>
添加Btn组件:
<template>
<v-btn class="btn" dark md color="success" @click="$emit('click-event')">
Add
</v-btn>
</template>
<script>
export default {};
</script>
<style></style>
我使用v-for列出API传入数据。
<v-row>
<v-list-item
v-for="(pair, index) in filterBy(pairs, search)"
:key="pair.symbol"
>
<v-list-item-content>
<v-list-item-title ref="refWord"
>{{ pair.symbol }} - {{ pair.price }}</v-list-item-title
>
</v-list-item-content>
<v-text-field
outlined
v-model="numberValue"
hide-details
single-line
type="number"
class="shrink mr-2"
width="50px"
height="50px"
/>
<AddBtn @click-event="searchHandle(index)" />
</v-list-item>
</v-row>
</v-form>
</v-card>
</v-dialog>
1条答案
按热度按时间kb5ga3dv1#
我认为您的问题来自于对spread语法(
...
)的过度使用。这是一个不错的ES6特性,但是当您在循环中使用它时应该非常小心。您使用的API返回了超过2,000个条目,并且对于每次迭代,您都在扩展两个数组,这将逐渐变得更加复杂。这是绝对没有必要的,当然,从性能方面来说,这是非常糟糕的。
我建议您使用
Array.prototype.push()
。使用JSBench.Me的一个简单测试显示了这两种策略之间的巨大差异: