如果你曾经开发过需要渲染大量数据的前端应用程序,那么你应该非常清楚数据表格的性能问题。当数据表格中的数据量超过几百条时,前端应用就会变得缓慢并且人机交互非常不流畅。这里将教你如何使用 Vue.js 优化大型数据表格渲染性能,让你的应用在处理大量数据时能够保持流畅的用户体验。
前期准备
要进行优化处理,首先我们需要使用到一些外部库和工具。以下是需要安装的工具和库:
在安装完这些工具之后,我们需要创建一个新的 Vue.js 项目。你可以通过下面的代码在本地创建一个 Vue.js 项目:
$ vue create vue-table-example
这里我们创建的项目名为 vue-table-example。
安装完项目之后,我们需要安装 lodash、axios 和 mock.js 库,分别使用下面的代码进行安装:
$ npm install --save lodash $ npm install --save axios $ npm install --save mockjs
至此,我们完成了前期的准备工作。
设计数据模型
首先,我们需要进行数据模型的设计。这里我们假设数据模型为一个简单的用户列表,包含 id、姓名、性别、年龄等属性。我们可以使用以下代码创建一个 Mock 数据模型:
// www.javascriptcn.com code example
import Mock from 'mockjs'
Mock.mock('/api/user-list', {
'user_list|1000': [{
'id|+1': 1,
'name': '@cname',
'gender|1': ['男', '女'],
'age|18-60': 1,
}]
})这里我们使用 Mock.js 来生成 1000 条随机用户数据,并将其输出到 /api/user-list 接口中,以便我们后续用 axios 库从后端读取数据。
列表渲染与优化
基础列表渲染
现在我们需要在前端使用 axios 库来获取后端数据,并使用 Vue.js 对数据进行渲染。为了简化代码,我们使用 Element UI 中的 el-table 组件来渲染数据表格,你也可以使用其他开源库来实现。
在进行列表数据渲染之前,我们需要先进行数据的获取。在 mounted 钩子函数中,我们使用以下代码来获取数据:
// www.javascriptcn.com code example
import axios from 'axios'
export default {
data() {
return {
userList: []
}
},
mounted() {
axios.get('/api/user-list').then(({ data }) => {
this.userList = data.user_list
})
}
}这里我们使用了 axios 库来从后端接口 /api/user-list 中获取数据,并将数据存储到 userList 变量中。
接下来,我们可以使用 el-table 组件来进行数据渲染。以下是一个简单的 el-table 示例:
// www.javascriptcn.com code example
<template>
<div>
<el-table :data="userList">
<el-table-column prop="id" label="ID"></el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="gender" label="性别"></el-table-column>
<el-table-column prop="age" label="年龄"></el-table-column>
</el-table>
</div>
</template>这里我们通过 el-table 组件来渲染数据表格。为了让表格能够自动根据数据进行渲染,我们在 el-table-column 中使用 prop 属性来指定渲染的数据字段。然后,我们在 mounted 钩子函数中使用 axios 库来获取后端数据。在数据获取后,我们将数据存储在 userList 变量中,并直接在模板中使用该变量进行渲染。
通过以上代码,我们成功渲染出了一个数据表格。然而,当数据量非常大时,性能会变得较差。因此,我们需要对数据表格进行优化。
v-if 优化
当数据量非常大时,你可以考虑使用 v-if 来优化性能。这里我们假设数据表格中有 10 万条数据,对于这种情况,我们对每一行记录都进行渲染,会导致我们的应用程序变得非常缓慢。因此,我们可以仅仅渲染可见区域内的数据对象。
以下是一个使用了 v-if 进行优化的示例代码:
// www.javascriptcn.com code example
<el-table :data="userList">
<el-table-column prop="id" label="ID"></el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="gender" label="性别"></el-table-column>
<el-table-column prop="age" label="年龄"></el-table-column>
<template v-if="userList.length">
<el-table-column label="操作">
<template slot-scope="scope">
<el-button @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</template>
</el-table>在这个示例中,我们仅在 userList 数组长度不为 0 时渲染删除按钮所在的整个列。这种方式可以极大地提高表格渲染性能,因为 Vue.js DOM diff 算法可以有效地处理只有选定记录的情况。
虚拟滚动优化
当数据量极大时,你可以考虑使用虚拟滚动进行优化。其实现方式是仅在可见区域渲染数据项。以下是一个简单的使用虚拟滚动进行优化的示例代码:
// www.javascriptcn.com code example
<el-table :data="visibleList">
<el-table-column prop="id" label="ID"></el-table-column>
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="gender" label="性别"></el-table-column>
<el-table-column prop="age" label="年龄"></el-table-column>
<template v-if="visibleList.length">
<el-table-column label="操作">
<template slot-scope="scope">
<el-button @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</template>
</el-table>当数据量非常大时,你可以考虑使用 el-table-infinite-scroll 组件来进行虚拟滚动。使用该组件,我们可以设置每页最多渲染的数据项数,并将数据项渲染方式从按每页渲染转换为按滚动渲染。以下是一个使用了 el-table-infinite-scroll 进行优化的示例代码:
// www.javascriptcn.com code example <el-table :data="userList" :row-class-name="handleClassName" @row-click="handleRowClick" ref="table" height="500" :fetch="fetchList" :loading="isLoading" > <el-table-column prop="id" label="ID"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="gender" label="性别"></el-table-column> <el-table-column prop="age" label="年龄"></el-table-column> </el-table>
在这个示例中,我们通过 fetch 函数从后端获取数据,并在 UI 中渲染可见的数据项。由于该函数只会在滚动到底部时触发,因此可以极大地提高数据渲染的性能。
小结
针对大型数据表格的渲染性能问题,我们可以使用多种方式进行优化。在这篇文章中,我们介绍了使用 v-if 和虚拟滚动进行优化的两种方式。当面对大量数据渲染时,应该结合实际情况选择合适的优化方式,以保证最佳的用户体验。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d7f900a941bf7134e3df89