Vue和Element-UI是一对非常好的组合,可以帮助我们非常快速地构建出有用的UI界面。在本文中,我将向您展示如何使用Vue和Element-UI实现数据的导航和筛选。
1. 准备工作
在开始前,我们需要在我们的项目中安装Vue和Element-UI。由于安装Vue和Element-UI是一个非常简单的过程,这里就不展开说明了。假设我们已经安装了它们,并且已经设置了一个Vue的实例,下面让我们开始实现数据导航和筛选:
2. 创建一个数据表格
首先,我们需要创建一个带有筛选功能的数据表格。我们将使用Element-UI的Table组件,它可以根据数据自动生成表格,并且可以非常方便地添加筛选功能。我们可以通过以下方式来创建一个表格:
<template>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="日期" width="180"></el-table-column>
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="address" label="地址"></el-table-column>
</el-table>
</template>
在这个例子中,我们定义了一个简单的数据表,其中包含了三个列:日期、姓名和地址。我们还将tableData作为表格的数据源,并通过prop属性将数据表中的列映射到我们的数据源中。
现在我们来试着运行一下这个例子,看看我们的表格是否能够正常地显示出来:
export default {
data() {
return {
tableData: [
{ date: '2016-05-03', name: '王小明', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-02', name: '张小刚', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-04', name: '李小红', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-01', name: '周小伟', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-08', name: '王小明', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-06', name: '张小刚', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-07', name: '李小红', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-05', name: '周小伟', address: '上海市普陀区金沙江路 1519 弄' }
]
};
}
};
然后我们来运行一下代码,看看我们的表格是否能够正常地显示出来:
![示例数据表格.png](https://cdn.nlark.com/yuque/0/2021/png/420095/1631237663218-ccb6d5b6-1a27-46e3-98d6-f476502259e6.png#clientId=ue35041e0-65a3-4&from=paste&height=363&id=uc40544b2&margin=%5Bobject%20Object%5D&name=%E7%A4%BA%E4%BE%8B%E6%95%B0%E6%8D%AE%E8%A1%A8%E6%A0%BC.png&originHeight=363&originWidth=595&originalType=binary&ratio=1&size=11567&status=done&style=none&taskId=u6d210ef4-57e3-4ad6-93a3-e15152cea16)
3. 添加筛选功能
现在我们已经创建了一个简单的数据表格,接下来我们将添加筛选功能。为此,我们使用Element-UI的 input 组件。我们可以将每个列的头部装饰器设置为一个 input 输入框,然后绑定 tableData 中对应的字段,并通过 filter-method 自定义筛选方法来实现筛选功能。下面是完整的代码:
<template>
<el-table :data="tableData" :header-cell-style="tableHeaderStyle">
<el-table-column prop="date" label="日期" width="180">
<template slot-scope="scope">
{{scope.row.date}}
<el-input v-model="search.date" size="mini" :placeholder="'搜索 ' + scope.column.label" @keyup.enter.native="handleSearch">
</el-input>
</template>
</el-table-column>
<el-table-column prop="name" label="姓名" width="180">
<template slot-scope="scope">
{{scope.row.name}}
<el-input v-model="search.name" size="mini" :placeholder="'搜索 ' + scope.column.label" @keyup.enter.native="handleSearch">
</el-input>
</template>
</el-table-column>
<el-table-column prop="address" label="地址">
<template slot-scope="scope">
{{scope.row.address}}
<el-input v-model="search.address" size="mini" :placeholder="'搜索 ' + scope.column.label" @keyup.enter.native="handleSearch">
</el-input>
</template>
</el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [
{ date: '2016-05-03', name: '王小明', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-02', name: '张小刚', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-04', name: '李小红', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-01', name: '周小伟', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-08', name: '王小明', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-06', name: '张小刚', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-07', name: '李小红', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-05', name: '周小伟', address: '上海市普陀区金沙江路 1519 弄' }
],
search: {
date: '',
name: '',
address: ''
}
};
},
methods: {
tableHeaderStyle({ column }) {
return { 'background-color': '#f7f7f7', 'font-weight': 'bold' };
},
handleSearch() {
const { date, name, address } = this.search;
const tableData = this.tableData.filter(item => {
return (
(date && item.date.toLowerCase().includes(date.toLowerCase())) ||
(name && item.name.toLowerCase().includes(name.toLowerCase())) ||
(address && item.address.toLowerCase().includes(address.toLowerCase()))
);
});
this.$refs.tableData.setCurrentRow(null);
this.$refs.tableData.clearSort();
this.$refs.tableData.setData(tableData);
}
}
};
可以看到,我们在每个列的头部添加了一个 input 组件,并将它们分别与 tableData 中的 date、name 和 address 字段进行了绑定。同时,我们还定义了一个 handleSearch 方法,该方法会根据每个 input 输入框中的值来筛选 tableData 中的数据,并通过 setData 方法将筛选后的数据重新渲染到表格中。这里还通过 setCurrentRow 和 clearSort 方法来清除当前表格中的排序状态。
现在让我们再次运行代码,看看我们的表格是否已经具备了筛选功能:
![运行后的数据表格.png](https://cdn.nlark.com/yuque/0/2021/png/420095/1631237747644-7b8c1755-25b5-4d08-b2f3-9af6fb1b69c5.png#clientId=ue35041e0-65a3-4&from=paste&height=363&id=u9d4d30d7&margin=%5Bobject%20Object%5D&name=%E8%BF%90%E8%A1%8C%E5%90%8E%E7%9A%84%E6%95%B0%E6%8D%AE%E8%A1%A8%E6%A0%BC.png&originHeight=363&originWidth=595&originalType=binary&ratio=1&size=12096&status=done&style=none&taskId=u5dfabf02-7ab3-488c-a5cc-6662d7d7ced)
4. 添加分页功能
现在我们已经实现了基本的数据导航和筛选功能,接下来我们将添加分页功能。同样,我们将使用 Element-UI 的 Pagination 组件来实现分页功能。我们需要将这个组件添加到我们的数据表格的下方,并绑定当前页码和每页显示的数据数量。
下面是完整的代码:
<template>
<div>
<el-table :data="tableData" :header-cell-style="tableHeaderStyle" ref="tableData">
<el-table-column prop="date" label="日期" width="180">
<template slot-scope="scope">
{{scope.row.date}}
<el-input v-model="search.date" size="mini" :placeholder="'搜索 ' + scope.column.label" @keyup.enter.native="handleSearch">
</el-input>
</template>
</el-table-column>
<el-table-column prop="name" label="姓名" width="180">
<template slot-scope="scope">
{{scope.row.name}}
<el-input v-model="search.name" size="mini" :placeholder="'搜索 ' + scope.column.label" @keyup.enter.native="handleSearch">
</el-input>
</template>
</el-table-column>
<el-table-column prop="address" label="地址">
<template slot-scope="scope">
{{scope.row.address}}
<el-input v-model="search.address" size="mini" :placeholder="'搜索 ' + scope.column.label" @keyup.enter.native="handleSearch">
</el-input>
</template>
</el-table-column>
</el-table>
<div style="text-align: right">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page.sync="currentPage" :page-sizes="[10, 20, 50]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="tableData.length"></el-pagination>
</div>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [
{ date: '2016-05-03', name: '王小明', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-02', name: '张小刚', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-04', name: '李小红', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-01', name: '周小伟', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-08', name: '王小明', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-06', name: '张小刚', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-07', name: '李小红', address: '上海市普陀区金沙江路 1519 弄' },
{ date: '2016-05-05', name: '周小伟', address: '上海市普陀区金沙江路 1519 弄' }
],
search: {
date: '',
name: '',
address: ''
},
currentPage: 1,
pageSize: 10
};
},
computed: {
filteredData() {
const { date, name, address } = this.search;
const tableData = this.tableData.filter(item => {
return (
(date && item.date.toLowerCase().includes(date.toLowerCase())) ||
(name && item.name.toLowerCase().includes(name.toLowerCase())) ||
(address && item.address.toLowerCase().includes(address.toLowerCase()))
);
});
return tableData.slice(
(this.currentPage - 1) * this.pageSize,
this.currentPage * this.pageSize
);
}
},
methods: {
tableHeaderStyle({ column }) {
return { 'background-color': '#f7f7f7', 'font-weight': 'bold' };
},
handleSearch() {
this.currentPage = 1;
},
handleSizeChange(val) {
this.pageSize = val;
},
handleCurrentChange(val) {
this.currentPage = val;
}
}
};
我们将 Pagination 组件添加到了数据表格的下方,并使用了 computed 计算属性来实现分页数据的计算。这个 computed 计算属性根据当前页码和页大小对数据进行了分页,并且每次搜索时都会重置当前页码,保证了搜索结果总是从第一页开始进行分页。
现在,我们再次运行代码,看看我们的表格是否已经具备了完整的数据导航、筛选和分页功能:
![具备完整功能的数据表格.png](https://cdn.nlark.com/yuque/0/2021/png/420095/1631237846543-8c35fbaf-b165-4fcf-8ef7-7a2f9b7b876f.png#clientId=ue35041e0-65a3-4&from=paste&height=381&id=ud9ec5a8e&margin=%5Bobject%20Object%5D&name=%E5%85%B7%E5%A4%87%E5%AE%8C%E6%95%B