Vue+Element 仿飞书表格||甘特图表格 ,搜索、筛选、字段管理、卡片管理功能
注明:此表格是表头自定义多类型筛选的升级版
·
一、整体效果图
二、选中数据效果
注明:此表格是表头自定义多类型筛选的升级版
- 涉及到的组件代码会以链接的形式贴出来
- 涉及到的Scss变量、样式、接口方法,请自行调试
- 列表的表头及每列数据均由后端返回
- 列表当中数据的状态颜色、tag标签均可配置
- 效果仅针对记录当前项目功能效果的实现
- Zn开头的组件为全局加载,请自行引入加载
- 列表无数据或无权限时prop传入图片路径及提示语即可,(此处可优化)
- 表格第一列序号与复选框hover切换
- 表格上方左侧为视图类别,类似tabs切换,类型不同,展示的数据形式也不同 , 比如下方数据展示有可能是列表, 有可能是card(创建视图功能暂未开发 , 目前只做了类型切换的展示 , 具体样子可去飞书观看一下)
三、页面示例代码
<template>
<div class="workOrder-container">
<zn-query-form>
<zn-query-form-left-panel>
<zn-views-tabs :options="viewsTabsOptions" @upTable="getHeader" />
</zn-query-form-left-panel>
<zn-query-form-right-panel>
<!-- 搜索 -->
<zn-search-btn @up-Search="upSearch" />
<!-- 筛选 -->
<zn-screen-btn
ref="ZnScreenBtn"
:mark="mark"
:views_id="queryForm.views_id"
:options="managementOptions"
@upTable="fetchData"
/>
<!-- 字段管理 -->
<zn-field-management-btn
ref="ZnFieldManagementBtn"
v-if="viewsType == 'table'"
:mark="mark"
:views_id="queryForm.views_id"
:options="managementOptions"
@upTable="upTableData"
/>
<!-- 卡片管理 -->
<zn-card-management-btn
ref="ZnCardManagementBtn"
v-if="viewsType == 'gallery'"
:mark="mark"
:views_id="queryForm.views_id"
:options="managementOptions"
@upCard="upCardData"
/>
<!-- 导出全部 -->
<el-button
type="primary"
size="medium"
plain
@click="reportAll"
v-permissions="{
permission: ['workOrder:workOrder:allWorkOrder:export'],
}"
>
<zn-icon :iconName="'emport'" />
导出
</el-button>
<el-button
class="el-add"
type="primary"
size="medium"
@click="addWorkOrder"
v-permissions="{ permission: ['workOrder:allWorkOrder:add'] }"
>
<zn-icon :iconName="'callcenter-add'" />
新建工单
</el-button>
</zn-query-form-right-panel>
</zn-query-form>
<!-- 相册试图页面 -->
<div
v-if="viewsType === 'gallery'"
class="content-view album-view"
v-infinite-scroll="loadMore"
:infinite-scroll-immediate="false"
>
<zn-filter-album
ref="filterAlbum"
:albumData="tableList"
:finallyColumns="finallyColumns"
:deatilsPath="deatilsPath"
:indexColumn="indexColumn"
@fetch-data="fetchData"
/>
</div>
<!-- 表格试图页面 -->
<div class="content-view table-view" v-else>
<zn-filter-table
v-if="viewsType == 'table'"
ref="filterTable"
:class="total === 0 ? 'table-view-empty' : ''"
:multiple="true"
:tableData="tableList"
:finallyColumns="finallyColumns"
:deatilsPath="deatilsPath"
@selectList="getSelect"
@fetch-data="fetchData"
:defaultPageImgUrl="
require('@/assets/images/default_page/pic-currency.png')
"
:defaultPageTips="'暂无数据'"
>
<el-button type="text" size="medium" @click="reportPart">
<zn-icon :iconName="'emport'" />
<span>导出选中</span>
</el-button>
</zn-filter-table>
<zn-pagination
v-show="total > 0"
:page.sync="queryForm.page"
:limit.sync="queryForm.listRows"
@pagination="fetchData"
:total="total"
:algin="'right'"
class="table-pagination"
/>
</div>
<add-work-order
:modalToBody="false"
:configData="configData"
ref="addWorkOrder"
/>
</div>
</template>
<script>
import addWorkOrder from './components/addWorkOrder'
import {
getList,
getWorkOrderConfig,
exportAllExcel,
exportSelectExcel,
} from '@/api/workOrder'
import { getTableHeader, viewsTabs, filters } from '@/api/index'
export default {
name: 'WorkOrder',
props: {},
components: {
addWorkOrder,
},
data() {
return {
mark: 'WorkOrderList',
configData: null,
viewsType: '', //当前页面显示视图类型
total: 0,
tableList: [],
viewsTabsOptions: [], // viewsTabs数据
managementOptions: {}, // 字段、卡片管理数据
listLoading: false,
queryForm: {
page: 1,
listRows: 10,
keywords: '',
views_id: '', //当前页面显示视图ID
},
deatilsPath: '/workOrder/workOrderDetail', //表格当前行跳转路径
columns: [], //筛选条件中的数据
checkList: [], //筛选条件中选中的数据
moreList: [], //表格复选多选中的数据
indexColumn: '', // 相册视图标题字段
}
},
computed: {
finallyColumns() {
if (this.checkList.length > 0) {
return this.columns.filter((item) =>
this.checkList.includes(item.label)
)
}
},
},
watch: {},
created() {
this.getConfigData()
this.getViewsTabs()
},
mounted() {},
methods: {
// 获取工单配置参数
getConfigData() {
getWorkOrderConfig().then((res) => {
this.configData = res.data
})
},
addWorkOrder() {
this.$refs['addWorkOrder'].show()
},
// 顶栏左侧viewsTabs
getViewsTabs() {
viewsTabs({ mark: this.mark }).then((res) => {
this.viewsTabsOptions = res.data
if (res.code == 200 && res.data.length > 0) {
this.queryForm.views_id = res.data[0].id // 更新当前页面显示视图ID
this.viewsType = res.data[0].type // 更新当前页面显示视图类型
this.getFilters() //回显筛选
this.getHeader()
if (res.data[0].type === 'table') {
this.fetchData()
} else {
this.fetchAlbumData()
}
}
})
},
// 获取已保存的筛选规则
getFilters() {
filters({ mark: this.mark, views_id: this.queryForm.views_id }).then(
(res) => {
if (this.$refs.ZnScreenBtn) {
this.$refs.ZnScreenBtn.form.filters = res.data.filters
}
}
)
},
// 顶栏右侧字段管理、卡片管理
async getHeader(obj) {
getTableHeader({
mark: this.mark,
views_id: obj ? obj.id : this.queryForm.views_id,
}).then((res) => {
this.managementOptions = res.data //字段管理、卡片管理
this.columns = res.data.fields //table列(未经卡片管理、字段管理筛选的数据)
this.indexColumn = res.data.options.indexColumn
if (obj) {
this.queryForm.views_id = obj.id // 更新当前页面显示视图ID
this.viewsType = obj.type // 更新当前页面显示视图类型
this.getFilters() //回显筛选
// 更新数据
if (obj.type === 'table') {
this.fetchData()
} else {
this.tableList = []
this.queryForm.page = 1
this.loadMore()
}
}
this.managementOptions.fields.map((item) => {
if (item.isShow == true) {
this.checkList.push(item.label)
}
})
})
},
// 请求table数据
async fetchData() {
this.listLoading = true
const {
data: { data, total },
} = await getList(this.queryForm)
this.tableList = data
this.total = total
this.listLoading = false
},
// 请求album数据
async fetchAlbumData() {
this.listLoading = true
const {
data: { data, total, last_page },
} = await getList(this.queryForm)
this.tableList = this.tableList.concat(data)
if (this.queryForm.page >= last_page + 1) {
this.queryForm.page = last_page + 1
} else {
this.queryForm.page = this.queryForm.page + 1
}
this.total = total
this.listLoading = false
},
// 更新搜索字段,更新table数据
upSearch(val) {
this.tableList = []
this.queryForm.page = 1
this.queryForm.keywords = val
if (this.viewsType === 'table') {
this.fetchData()
} else {
this.loadMore()
}
},
// 获取多选选中的table数据(需求未出,功能暂留)
getSelect(list) {
this.moreList = list
},
// 卡片管理子组件条件返回,更新表格视图
upTableData(columns, checkList) {
this.columns = columns //所有表头
this.checkList = checkList //对应表头
},
// 卡片管理子组件条件返回,更新表格视图
upCardData(columns, checkList, showLabel) {
this.columns = columns //所有表头
this.checkList = checkList //对应表头
this.showLabel = showLabel //卡片视图中是否显示label
},
// 无线加载
loadMore() {
this.queryForm.listRows = 6
this.fetchAlbumData()
},
// 导出选中
reportPart() {
exportSelectExcel({
views_id: this.queryForm.views_id,
ids: this.moreList.map((item) => item.id).join(','),
}).then((res) => {
if (res.code === 200) {
this.$download(res.data)
}
})
},
// 导出全部
reportAll() {
exportAllExcel({
views_id: this.queryForm.views_id,
keywords: this.queryForm.keywords,
}).then((res) => {
if (res.code === 200) {
this.$download(res.data)
}
})
},
},
}
</script>
<style lang="scss" scoped>
.workOrder-container {
height: calc(100vh - 60px - 50px - 16px * 2);
::v-deep .add-workorder-drawer {
position: absolute;
}
.el-add {
margin-right: 0 !important;
}
.content-view {
height: calc(100% - 55px);
&.album-view {
overflow-x: hidden;
overflow-y: auto;
padding: 0 16px 16px;
}
&.table-view {
position: relative;
}
// 分页样式
.filter-table {
height: calc(100% - 69px);
padding-bottom: 0;
&.table-view-empty {
height: 100%;
}
::v-deep .el-table {
height: 100%;
.el-table__body-wrapper {
height: calc(100% - 48px);
overflow: auto;
}
}
}
}
}
</style>
四、总结
- 功能很强,但是也有局限性,适用于瀑布流开发模式
- 页面调用的这个层级其实还可以再封装一层
- 有些地方是需要再优化的,由于需求一直在变,也无心高度优化(每个版本都要动这里面的东西,心累)
五、github源码链接
github源码链接,代码中有数据示例
更多推荐
已为社区贡献25条内容
所有评论(0)