提交 392e0f49 编写于 作者: 沐夕花开's avatar 沐夕花开

feat: 新增分组模式(开发中)

上级 4517c064
<template> <template>
<view class="container"> <view class="container">
<n-table <!-- <n-table
:headerOpt="headerOpt" :headerOpt="headerOpt"
:nameOpt="{isShow:true, title: '示例2', needMenu: false, align: 'center'}" :nameOpt="{isShow:true, title: '示例2', needMenu: false, align: 'center'}"
:tableOpt="{isShowSum:true,fontSize:14}" :tableOpt="{isShowSum:true,fontSize:14}"
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
<view class="btn-wrap"> <view class="btn-wrap">
<button size="mini" class="ep-btn" type="primary" @click="toggleColumnHidden">显示/隐藏</button> <button size="mini" class="ep-btn" type="primary" @click="toggleColumnHidden">显示/隐藏</button>
</view> </view>
</view> </view> -->
<!-- 树形表格 --> <!-- 树形表格 -->
<n-table <!-- <n-table
:headerOpt="{}" :headerOpt="{}"
:nameOpt="{isShow:true, title: '树形表格+默认展开',needMenu:true}" :nameOpt="{isShow:true, title: '树形表格+默认展开',needMenu:true}"
:tableOpt="{}" :tableOpt="{}"
...@@ -30,12 +30,24 @@ ...@@ -30,12 +30,24 @@
<view class="info-tx"> <view class="info-tx">
props.defaultOpen = true 控制是否默认展开全部(树形结构) 默认值 false props.defaultOpen = true 控制是否默认展开全部(树形结构) 默认值 false
</view> </view> -->
<n-table
:headerOpt="headerOpt"
:nameOpt="{isShow:true, title: '分组', needMenu: false, align: 'center'}"
:tableOpt="{isShowSum:true,fontSize:14}"
isGroup
:tableHeight="0"
:tableData="tableData4"
:columns="columns4"
:pagerOpt="{show:true,pageSize: 4,btnFontSize:14, btnFontColor: '#2b85e4', numFontColor: '#fa3534'}"
colKey="dataIndex"
idKey="key"></n-table>
</view> </view>
</template> </template>
<script> <script>
import { tableData2, columns2, columns3, treeColumnsData } from "./tableData.js" import { tableData2, columns2, columns3, treeColumnsData, groupData } from "./tableData.js"
export default { export default {
data() { data() {
return { return {
...@@ -46,7 +58,10 @@ ...@@ -46,7 +58,10 @@
tableData3: false, // 树形数据 tableData3: false, // 树形数据
columns3: false, // 树形 columns3: false, // 树形
columns4: false, // 分组
tableData4: false, // 分组
defaultOpen: true, defaultOpen: true,
} }
}, },
...@@ -65,14 +80,18 @@ ...@@ -65,14 +80,18 @@
this.columns3 = JSON.parse(JSON.stringify(columns3)) this.columns3 = JSON.parse(JSON.stringify(columns3))
this.tableData3 = JSON.parse(JSON.stringify(treeColumnsData)) this.tableData3 = JSON.parse(JSON.stringify(treeColumnsData))
this.columns4 = JSON.parse(JSON.stringify(columns3))
this.tableData4 = JSON.parse(JSON.stringify(groupData))
} }
} }
</script> </script>
<style scoped> <style scoped>
.container{ .container {
padding-bottom: 30px; padding-bottom: 30px;
} }
.info-tx { .info-tx {
padding: 10px; padding: 10px;
font-size: 12px; font-size: 12px;
......
...@@ -268,4 +268,59 @@ export const columns3 = [{ ...@@ -268,4 +268,59 @@ export const columns3 = [{
"title": "达成排名", "title": "达成排名",
"dataIndex": "达成排名" "dataIndex": "达成排名"
} }
] ]
\ No newline at end of file
export const groupData = [{
"key": 1,
"区域": "广州",
"销售": 100,
"计划销售": 200,
"达成": "50.0%",
"达成排名": 1,
"GroupIndex": 1,
"GroupLayer": 1,
"GroupKey": "广州",
"children": [{
"key": 11,
"区域": "广州一区",
"小区": "广州一区",
"销售": 60,
"计划销售": 120,
"达成": "50.0%",
"达成排名": 1,
},
{ "key": 12, "区域": "广州二区", "小区": "广州二区", "销售": 40, "计划销售": 80, "达成": "50.0%", "达成排名": 1 },
],
},
{
"key": 2,
"区域": "深圳",
"销售": 200,
"计划销售": 300,
"达成": "66.7%",
"达成排名": 2,
"GroupIndex": 1,
"GroupLayer": 1,
"GroupKey": "深圳",
"children": [
{ "key": 21, "区域": "深圳一区", "小区": "深圳一区", "销售": 110, "计划销售": 150, "达成": "73.3%", "达成排名": 2 },
{ "key": 22, "区域": "深圳二区", "小区": "深圳二区", "销售": 90, "计划销售": 150, "达成": "60.0%", "达成排名": 1 },
],
},
{
"key": 3,
"区域": "北京",
"销售": 300,
"计划销售": 200,
"达成": "150.0%",
"达成排名": 3,
"GroupIndex": 1,
"GroupLayer": 1,
"GroupKey": "北京",
"children": [
{ "key": 31, "区域": "北京一区", "小区": "北京一区", "销售": 70, "计划销售": 60, "达成": "116.7%", "达成排名": 1 },
{ "key": 32, "区域": "北京二区", "小区": "北京二区", "销售": 120, "计划销售": 60, "达成": "200.0%", "达成排名": 3 },
{ "key": 33, "区域": "北京三区", "小区": "北京三区", "销售": 110, "计划销售": 80, "达成": "137.5%", "达成排名": 2 },
],
}
]
<template>
<view class="group-body">
</view>
</template>
<script>
export default {
name: 'groupBody',
data() {
return {
}
}
}
</script>
<style>
</style>
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
:isTree="isTree" :isTree="isTree"
@rowSort="onRowSort" @rowSort="onRowSort"
@toggleTree="onToggleTree"></table-header> @toggleTree="onToggleTree"></table-header>
<table-body <table-body
:isOpenAll="isOpenAll" :isOpenAll="isOpenAll"
:isShowSum="_tableOpt.isShowSum" :isShowSum="_tableOpt.isShowSum"
...@@ -40,6 +41,7 @@ ...@@ -40,6 +41,7 @@
:colKey="colKey" :colKey="colKey"
:isTree="isTree" :isTree="isTree"
:default-open="defaultOpen" :default-open="defaultOpen"
:isGroup="isGroup"
@toggleTree="onToggleTree" @toggleTree="onToggleTree"
@onClick="onColClick" @onClick="onColClick"
:dataList="dataList"> :dataList="dataList">
...@@ -129,7 +131,8 @@ ...@@ -129,7 +131,8 @@
currentPage: { type: [Number, Boolean], default: false }, currentPage: { type: [Number, Boolean], default: false },
// 总页数 // 总页数
totalPage: { type: Number, default: 1 }, totalPage: { type: Number, default: 1 },
defaultOpen: { type: Boolean, default: false } defaultOpen: { type: Boolean, default: false },
isGroup: { type: Boolean, default: false }
}, },
computed: { computed: {
...@@ -269,7 +272,7 @@ ...@@ -269,7 +272,7 @@
// 不分页 // 不分页
dataList = list dataList = list
} }
this.dataList = this.listFmt(dataList, 0) this.dataList = this.isGroup ? this.listFmtGroup(dataList) : this.listFmt(dataList, 0)
// 计算总计行 // 计算总计行
if (this._tableOpt.isShowSum) { if (this._tableOpt.isShowSum) {
this.setSumRow() this.setSumRow()
...@@ -306,6 +309,7 @@ ...@@ -306,6 +309,7 @@
// 递归处理数据,tree => Array // 递归处理数据,tree => Array
listFmt(list, level, parentIds = []) { listFmt(list, level, parentIds = []) {
console.log(' =====> listFmt');
return list.reduce((ls, item) => { return list.reduce((ls, item) => {
let { children, ...res } = item let { children, ...res } = item
// 错误提示 // 错误提示
...@@ -328,6 +332,15 @@ ...@@ -328,6 +332,15 @@
return ls return ls
}, []) }, [])
}, },
// 格式化
listFmtGroup(list) {
return list.reduce((ls, item) => {
return ls.concat({ ...item, open: false })
}, [])
// return [...list]
},
getPageSize(selecter) { getPageSize(selecter) {
// 获取元素信息 // 获取元素信息
let query = uni.createSelectorQuery().in(this), let query = uni.createSelectorQuery().in(this),
......
<template> <template>
<view> <view class="body-wrapper" ref="bodyWrapper" id="bodyWrapper">
<template v-for="(row, iIndex) in dataList"> <template v-for="(row, iIndex) in dataList">
<view class="n-table-container-row" <!-- 分组 -->
v-if="row.level === 0 || checkOpen(row.parentIds[row.parentIds.length - 1])" <template v-if="isGroup">
:key="iIndex"> <view class="n-table-container-row group-row" :key="iIndex">
<template v-for="(col, jIndex) in dataIndexs"> <view class="" v-if="row.children">
<view <view class="n-table-container-col head-row group-col"
v-if="!col.hidden" style="text-align: left;"
:class="['n-table-container-col', { 'head-row': jIndex == 0, 'n-table-stick-side': stickSide && jIndex == 0 , 'text-left': textAlign === 'left' && !isTree, 'text-center': textAlign === 'center' && !isTree, 'text-right': textAlign === 'right' && !isTree }]" :style="{width: '100vw', backgroundColor: '#fff', borderRight: 0}">
:style="{ {{row.GroupKey}}
width: getItemStyle(col).width,
paddingLeft: jIndex == 0 ? ( isTree ? (row.level + 1) : row.level )*8 + 'px' : '8px',
}"
:key="jIndex" @click.stop="itemClick(row, col)">
<!-- 展开 -->
<view
class="open-child"
v-if="jIndex === 0"
@click.stop="toggleOpen(row)">
<view <view
v-if="row.hasChildren"
class="iconfont" class="iconfont"
style="font-size: 12px;" style="font-size: 12px;"
:class="checkOpen(row[idKey]) ? 'icon-arrow-up' : 'icon-arrow-down'"></view> @click="openGroup(row)"
<view class="" v-else style="padding-left:20rpx;"> </view> :class="row.open ? 'icon-arrow-up' : 'icon-arrow-down'"></view>
</view> </view>
<template v-if="row.open">
<view v-for=" (child, childIdx) in row.children" :key="childIdx">
<view v-for="(col, jIndex) in dataIndexs"
:class="['n-table-container-col', { 'head-row': jIndex == 0, 'n-table-stick-side': stickSide && jIndex == 0 , 'text-left': textAlign === 'left' && !isTree, 'text-center': textAlign === 'center' && !isTree, 'text-right': textAlign === 'right' && !isTree }]"
:style="{
width: getItemStyle(col).width,
paddingLeft: jIndex == 0 ? ( isTree ? (row.level + 1) : row.level )*8 + 'px' : '8px',
}">
<view
:class="['n-table-col-text', {'text-left': getTextAlign(col) === 'left' || jIndex === 0 , 'text-center': getTextAlign(col) === 'center' && jIndex !== 0, 'text-right': getTextAlign(col) === 'right' && jIndex !== 0}]"
:style="{color: col.bodyColor || color, fontSize: fontSize + 'px'}">
<view class="tx-content" v-if="!col.isLink && !col.isImage"
v-html="getRowContent(child, col)">
</view>
</view>
</view>
</view>
</template>
</view>
</view>
</template>
<!-- 其他 -->
<template v-if="!isGroup">
<view class="n-table-container-row"
v-if="row.level === 0 || checkOpen(row.parentIds[row.parentIds.length - 1])"
:key="iIndex">
<template v-for="(col, jIndex) in dataIndexs">
<view <view
:class="['n-table-col-text', {'text-left': getTextAlign(col) === 'left' || jIndex === 0 , 'text-center': getTextAlign(col) === 'center' && jIndex !== 0, 'text-right': getTextAlign(col) === 'right' && jIndex !== 0}]" v-if="!col.hidden"
:style="{color: col.bodyColor || color, fontSize: fontSize + 'px'}"> :class="['n-table-container-col', { 'head-row': jIndex == 0, 'n-table-stick-side': stickSide && jIndex == 0 , 'text-left': textAlign === 'left' && !isTree, 'text-center': textAlign === 'center' && !isTree, 'text-right': textAlign === 'right' && !isTree }]"
<view class="tx-content" v-if="!col.isLink && !col.isImage" :style="{
v-html="getRowContent(row, col)"> width: getItemStyle(col).width,
paddingLeft: jIndex == 0 ? ( isTree ? (row.level + 1) : row.level )*8 + 'px' : '8px',
}"
:key="jIndex" @click.stop="itemClick(row, col)">
<!-- 展开 -->
<view
class="open-child"
v-if="jIndex === 0"
@click.stop="toggleOpen(row)">
<view
v-if="row.hasChildren"
class="iconfont"
style="font-size: 12px;"
:class="checkOpen(row[idKey]) ? 'icon-arrow-up' : 'icon-arrow-down'"></view>
<view class="" v-else style="padding-left:20rpx;"> </view>
</view> </view>
<!-- 图片 --> <view
<view v-if="col.isImage" class="n-table-col-img"> :class="['n-table-col-text', {'text-left': getTextAlign(col) === 'left' || jIndex === 0 , 'text-center': getTextAlign(col) === 'center' && jIndex !== 0, 'text-right': getTextAlign(col) === 'right' && jIndex !== 0}]"
<image :style="{color: col.bodyColor || color, fontSize: fontSize + 'px'}">
v-if="row[col[colKey]]" <view class="tx-content" v-if="!col.isLink && !col.isImage"
@click="preViewImg(row[col[colKey]])" v-html="getRowContent(row, col)">
:src="row[col[colKey]]" mode="heightFix"
:style="{width: col.width ? col.width + 'px' : '32px', height:col.height ? col.height + 'px' : '32px'}">
</image>
<view class="" v-else>
-
</view> </view>
</view>
<!-- 链接 --> <!-- 图片 -->
<template v-if="col.isLink"> <view v-if="col.isImage" class="n-table-col-img">
<!-- #ifdef H5 --> <image
<router-link v-if="setUrl(row, col).indexOf('http') != 0" v-if="row[col[colKey]]"
:to="setUrl(row, col)" v-html="getRowContent(row, col)"></router-link> @click="preViewImg(row[col[colKey]])"
<a v-else :href="setUrl(row, col)" :src="row[col[colKey]]" mode="heightFix"
v-html="getRowContent(row, col)"></a> :style="{width: col.width ? col.width + 'px' : '32px', height:col.height ? col.height + 'px' : '32px'}">
<!-- #endif --> </image>
<view class="" v-else>
<!-- #ifndef H5 --> -
<navigator :url="setUrl(row, col)" </view>
v-html="getRowContent(row, col)"></navigator> </view>
<!-- #endif -->
</template>
</view> <!-- 链接 -->
<template v-if="col.isLink">
<!-- #ifdef H5 -->
<router-link v-if="setUrl(row, col).indexOf('http') != 0"
:to="setUrl(row, col)" v-html="getRowContent(row, col)"></router-link>
<a v-else :href="setUrl(row, col)"
v-html="getRowContent(row, col)"></a>
<!-- #endif -->
<!-- #ifndef H5 -->
<navigator :url="setUrl(row, col)"
v-html="getRowContent(row, col)"></navigator>
<!-- #endif -->
</template>
</view> </view>
</template>
</view> </view>
</template>
</view>
</template>
</template> </template>
</view> </view>
</template> </template>
...@@ -93,15 +134,27 @@ ...@@ -93,15 +134,27 @@
type: Boolean, type: Boolean,
default: false default: false
}, },
defaultOpen: { type: Boolean, default: false } defaultOpen: { type: Boolean, default: false },
isGroup: { type: Boolean, default: false }
}, },
data() { data() {
return { return {
openList: [], openList: [],
canOpenObj: {}, // 保存所有能展开的列Id canOpenObj: {}, // 保存所有能展开的列Id
needToogleTree: true needToogleTree: true,
wrapperWidth: null
} }
}, },
mounted() {
setTimeout(() => {
console.log(' =====> 1', 1);
let query = uni.createSelectorQuery().in(this)
query.select('#bodyWrapper').boundingClientRect(data => {
console.log(' =====> data', data);
this.wrapperWidth = data.width + 'px'
}).exec()
}, 0)
},
watch: { watch: {
isOpenAll: { isOpenAll: {
handler(val) { handler(val) {
...@@ -122,14 +175,22 @@ ...@@ -122,14 +175,22 @@
}, },
deep: true, deep: true,
immidate: true immidate: true
},
isGroup: {
handler(val) {
console.log('isGroup =====> val', val);
},
immediate: true
} }
}, },
methods: { methods: {
// 默认打开全部 // 默认打开全部
initDefaultOpen(list) { initDefaultOpen(list) {
console.log(' initDefaultOpen =====> ', 1);
this.openList = list.reduce((ls, item) => { this.openList = list.reduce((ls, item) => {
return item.hasChildren ? ls.concat(item[this.idKey]) : ls return item.hasChildren ? ls.concat(item[this.idKey]) : ls
}, []) }, [])
console.log(' initDefaultOpen =====> ', 2);
}, },
getTextAlign(col) { getTextAlign(col) {
return col.textAlign || this.textAlign return col.textAlign || this.textAlign
...@@ -151,6 +212,7 @@ ...@@ -151,6 +212,7 @@
// 更新可展开id对象 // 更新可展开id对象
updataCanOpen(list) { updataCanOpen(list) {
console.log(' =====> updataCanOpen - start');
if (!list || !list.length) { if (!list || !list.length) {
this.canOpenObj = {} this.canOpenObj = {}
return return
...@@ -162,6 +224,7 @@ ...@@ -162,6 +224,7 @@
item[this.idKey]), []) item[this.idKey]), [])
return obj return obj
}, {})) }, {}))
console.log(' =====> updataCanOpen - end');
}, },
// 点击行展开、收起时触发 // 点击行展开、收起时触发
...@@ -279,6 +342,7 @@ ...@@ -279,6 +342,7 @@
// 判断是否展开子列 // 判断是否展开子列
checkOpen(id) { checkOpen(id) {
console.log('checkOpen =====> id', id);
return ~this.openList.findIndex(o => o === id); return ~this.openList.findIndex(o => o === id);
}, },
...@@ -312,6 +376,11 @@ ...@@ -312,6 +376,11 @@
return tempUrl return tempUrl
}, },
openGroup(row) {
row.open = !row.open
}
} }
} }
</script> </script>
...@@ -325,7 +394,7 @@ ...@@ -325,7 +394,7 @@
white-space: nowrap; white-space: nowrap;
box-sizing: border-box; box-sizing: border-box;
z-index: 0; z-index: 0;
border-bottom: solid 1rpx #f4f4f4; // border-bottom: solid 1rpx #f4f4f4;
box-sizing: border-box; box-sizing: border-box;
} }
...@@ -344,7 +413,7 @@ ...@@ -344,7 +413,7 @@
position: sticky; position: sticky;
left: 0; left: 0;
background: #f7f9ff; background: #f7f9ff;
border-right: solid 1rpx #dbdbdb; // border-right: solid 1rpx #dbdbdb;
box-sizing: border-box; box-sizing: border-box;
} }
...@@ -400,4 +469,29 @@ ...@@ -400,4 +469,29 @@
overflow: hidden; overflow: hidden;
word-break: break-all; word-break: break-all;
} }
.group-col {
display: flex;
justify-content: space-between;
padding-left: 10px;
padding-right: 10px;
position: sticky;
left: 0;
background: #e5e5e5;
// border-right: solid 1rpx #dbdbdb;
box-sizing: border-box;
.iconfont {
padding: 5rpx 20rpx;
}
}
.group-row {
position: sticky;
left: 0;
background: #f9f8f8;
border-right: solid 1rpx #dbdbdb;
box-sizing: border-box;
}
</style> </style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册