我的vue应用存在很大的性能问题。
我有约50行的表,它具有slot-scope =“ scope”属性 例如,当我尝试在选定的行上进行某些事件时,例如打开“元素UI”,则选择元素整个页面会冻结很长时间。
我检查了chrome webdev的“性能”选项卡,看起来该站点正在执行许多函数调用:
如果我的表中只有几行,它的工作速度很快。
这是我的组件代码:
<template>
<div>
<el-card>
<div slot="header">
Quotes
<el-button
type="primary"
size="small"
@click="exportQuotes"
icon="el-icon-download"
class="pull-right card-header-item">
Export
</el-button>
<el-button
type="success"
size="small"
@click="$router.push({name: 'quote-create'})"
icon="el-icon-plus"
class="pull-right card-header-item">
Create new quote
</el-button>
</div>
<el-table
:data="quotes"
size="small"
style="width: 100%"
:row-class-name="tableRowHighlight"
v-loading="loading">
<el-table-column prop="ref_number" label="Ref #" width="107">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit Ref #:"
width="150"
v-model="scope.row.ref_number_edit"
@show="tmp_value = scope.row.ref_number">
<el-form
@submit.prevent="updateRefNumber(scope.row, tmp_value)"
inline
size="mini">
<el-input
type="text"
v-model="tmp_value"
size="mini"
class="pull-left"
style="width: 100px;margin-right:5px">
</el-input>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateRefNumber(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.ref_number_edit = true">{{ scope.row.ref_number }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="created_date" label="Date"></el-table-column>
<el-table-column prop="work_type" label="Work type"></el-table-column>
<el-table-column prop="address_state" label="State" width="40"></el-table-column>
<el-table-column prop="customer_name" label="Customer"></el-table-column>
<el-table-column prop="address_name" label="Site"></el-table-column>
<el-table-column prop="po" label="PO #"></el-table-column>
<el-table-column prop="description" label="Description"></el-table-column>
<el-table-column prop="scope" label="Scope"></el-table-column>
<el-table-column prop="av" label="A/V" align="center" width="40"></el-table-column>
<el-table-column prop="si" label="S/I" align="center"></el-table-column>
<el-table-column prop="service_provider_name" label="Service Provider"></el-table-column>
<el-table-column prop="status" label="Status">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit status:"
width="230"
v-model="scope.row.status_edit"
@show="tmp_value = scope.row.status">
<el-form
@submit.prevent="updateStatus(scope.row, tmp_value)"
inline
size="mini">
<el-select
v-model="tmp_value"
size="mini"
style="width: 180px;margin-right:5px">
<el-option
v-for="(label, key) in statuses"
:key="key"
:label="label"
:value="key">
</el-option>
</el-select>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateStatus(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.status_edit = true">{{ scope.row.status }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="days_to_quote" label="Days to Quote" align="center">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit days to quote:"
width="150"
v-model="scope.row.days_to_quote_edit"
@show="tmp_value = scope.row.days_to_quote">
<el-form
@submit.prevent="updateDaysToQuote(scope.row, tmp_value)"
inline
size="mini">
<el-input-number
type="text"
v-model="tmp_value"
size="mini"
class="pull-left"
style="width: 100px;margin-right:5px">
</el-input-number>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateDaysToQuote(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.days_to_quote_edit = true">{{ scope.row.days_to_quote }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="api_cost" label="API Cost" align="right">
<template slot-scope="scope">
<el-popover
placement="bottom"
title="Edit API cost:"
width="130"
v-model="scope.row.api_cost_edit"
@show="tmp_value = scope.row.api_cost">
<el-form
@submit.prevent="updateApiCost(scope.row, tmp_value)"
inline
size="mini">
<el-input-number
type="text"
v-model="tmp_value"
:precision="2"
size="mini"
:controls="false"
class="pull-left"
style="width: 105px">
</el-input-number>
<el-button
type="primary"
native-type="submit"
icon="el-icon-check"
size="mini"
@click="updateApiCost(scope.row, tmp_value)">
</el-button>
</el-form>
<span slot="reference" @click="scope.row.api_cost_edit = true">{{ scope.row.api_cost }}</span>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="customer_cost" label="Customer Cost" align="right">
<template slot-scope="scope">{{ scope.row.customer_cost }}</template>
</el-table-column>
<el-table-column prop="gpm" label="GPM" align="right">
<template slot-scope="scope">{{ scope.row.gpm }}%</template>
</el-table-column>
<el-table-column prop="total_approved" label="Total Approved" align="right">
<template slot-scope="scope">{{ scope.row.total_approved }}</template>
</el-table-column>
<el-table-column prop="total_approved_api" label="Total Approved API" align="right">
<template slot-scope="scope">{{ scope.row.total_approved_api }}</template>
</el-table-column>
<el-table-column prop="total_rejected" label="Total Rejected" align="right">
<template slot-scope="scope">{{ scope.row.total_rejected }}</template>
</el-table-column>
<el-table-column prop="margin_approved" label="Margin on Approved" align="right">
<template slot-scope="scope">{{ scope.row.margin_approved }}</template>
</el-table-column>
<el-table-column prop="total_pending" label="Total Pending" align="right">
<template slot-scope="scope">{{ scope.row.total_pending }}</template>
</el-table-column>
<el-table-column label="Actions" align="center" width="100" fixed="right">
<template slot-scope="scope">
<el-button
type="primary"
size="mini"
icon="el-icon-edit"
@click="editQuote(scope.row.id)">
</el-button>
<el-button
type="danger"
size="mini"
icon="el-icon-delete"
@click.prevent.stop="deleteQuote(scope.row.id, $event)">
</el-button>
</template>
</el-table-column>
<template slot="empty">
<p>
You don't have any saved quotes yet.<br>
</p>
</template>
</el-table>
<div class="pagination">
<el-pagination
background
small
layout="prev, pager, next"
@current-change="changePage"
:page-size="per_page"
:current-page="current_page"
:total="total">
</el-pagination>
</div>
</el-card>
</div>
</template>
<script>
export default {
data () {
return {
tmp_value: '',
loading: false,
per_page: null,
current_page: null,
total: null,
quotes: [],
statuses: []
}
},
methods: {
editQuote (quoteId) {
this.$router.push({
name: 'quote-edit',
params: { quoteId: quoteId }
})
},
viewQuote (quoteId) {
this.$router.push({
name: 'quote-view',
params: { quoteId: quoteId }
})
},
tableRowHighlight ({row, rowIndex}) {
if (row.status == 'APPROVED') {
return 'bg-success'
} else if (row.status == 'REJECTED') {
return 'bg-danger'
} else {
return ''
}
},
fetchQuotes () {
this.loading = true
this.$http
.get('/quotes', {
params: { page: this.current_page }
})
.then(res => {
this.loading = false
this.statuses = res.data.statuses
this.quotes = res.data.quotes.data
console.log(this.quotes)
this.current_page = res.data.quotes.current_page
this.per_page = res.data.quotes.per_page
this.total = res.data.quotes.total
})
.catch(err => {
this.loading = false
console.log(err)
})
},
changePage (page) {
this.current_page = page
this.fetchQuotes()
},
exportQuotes () {
window.open('/quotes/export', '_blank');
},
updateApiCost (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {api_cost: value})
.then(res => {
quote.api_cost_edit = false
this.fetchQuotes()
this.$message({
message: 'API cost has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateRefNumber (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {ref_number: value})
.then(res => {
quote.ref_number_edit = false
this.fetchQuotes()
this.$message({
message: 'Reference # has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateStatus (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {status: value})
.then(res => {
quote.status_edit = false
this.fetchQuotes()
this.$message({
message: 'Status has been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
updateDaysToQuote (quote, value) {
this.$http
.post('/quotes/' + quote.id + '/inline', {days_to_quote: value})
.then(res => {
quote.days_to_quote_edit = false
this.fetchQuotes()
this.$message({
message: 'Days to quote have been successfuly updated.',
type: 'success'
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
},
deleteQuote (quoteId) {
this.$confirm('Are you sure you want to delete this quote?', 'Warning', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning'
})
.then(() => {
this.$http
.delete('/quotes/' + quoteId)
.then(res => {
this.fetchQuotes()
this.$message({
type: 'success',
message: res.data.message
})
})
.catch(err => {
this.showErrorAlert(err.response.data.message)
})
})
.catch(err => {
console.log(err);
})
},
showErrorAlert (message) {
message = '<b>' + message + '</b><br>Please contact with administrator to fix this issue.'
this.$alert(message, 'Error', {
dangerouslyUseHTMLString: true,
confirmButtonText: 'OK',
type: 'error',
center: true
})
}
},
mounted () {
this.fetchQuotes()
}
}
</script>
<style lang="scss" scoped>
.pagination {
float: right;
margin: 20px 0
}
</style>
希望你们会帮助我找到解决方案。 谢谢!