uniapp页面一般都会有像以下的列表页面,封装通用组件,提高开发效率;
(基于uView前端框架)
首先,通过设计图来分析一下页面展示和数据结构定义
w-table组件参数说明
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
toggle | 列表是否带更多和收起功能 toggle值为true时,配合 prop-list 中定义的show字段使用,show值为true时,收起情况下默认展示的列,false则默认不展示,点击更多展开时展示toggle值为false时, prop-list 中定义的show值无效,表示全部默认展示,不需要展开收缩功能 | boolean | true|false | true |
prop-list | 定义的字段和列标题数组(对应PC端封装表格组件,内容格式一致) 例:[{label:‘废物名称’,prop:‘name’},{label:‘数字识别码’,prop:‘code’}] | array | – | [] |
table-data | 后台返回数据数组 | array | – | [] |
prop-list具体参数说明
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
label | 列的标题名称(如图:废物名称) | string | – | – |
prop | 字段名 | array | – | [] |
show | 列表收起时默认展示,toggle 为true 时生效 | string | true|false | false |
formatItem | 整体列插槽(例如上图俩个状态按钮列,不展示左边标题名称,则需要整体插槽实现) | boolean | true|false | false |
formatValue | 值插槽(例如返回值需要加单位,格式化等情况)formatItem 为true 时此属性不生效 | boolean | true|false | false |
propList数据格式
propList:[
{label:'废物名称',prop:'title',show:true},
{label:'数字识别码',prop:'name',show:true},
{label:'危废标识',prop:'tag',show:true},
{label:'废物代码',prop:'code',show:true},
{label:'废物重量',prop:'weight',formatValue:true,show:true},//格式化值
{label:'废物形态',prop:'name'},
{label:'主要成分',prop:'name'},
{label:'有害成分',prop:'name'},
{label:'危险特性',prop:'name'},
{label:'注意事项',prop:'name'},
{label:'产生/收集单位',prop:'comp'},
{label:'联系人',prop:'userName'},
{label:'联系方式',prop:'phone'},
{label:'产生日期',prop:'date'},
{label:'备注',prop:'remark'},
{label:'状态',prop:'status',formatItem:true,show:true},//格式化列默认展示
{label:'二维码',prop:'qrcode',formatItem:true,show:false}//格式化列默认不展示
]
tableData数据格式
tableData:[{
title:'HWCS20230908003',
time:'2023-09-18 14:00',
name:'废物名称',
code:'1234567890123456789000030420230915101',
tag:'7b9e9d22ca714365a1f6a6b338fc8fa3',
code1:'900-041-49',
weight:'30',
unit:'kg',
wasteStatus:1,
reportStatus:0,
}]
具体代码
基础用法
<w-table :table-data="tableData" :prop-list="propList" :toggle="true"></w-table>
有格式化值和列的情况
<w-table :table-data="tableData" :prop-list="propList" :toggle="true">
<template slot="header" slot-scope="scope">
<view class="width w-flex row row-between borderB padding16">
<view class="flex1 w-flex row">
<text class="fs24 c-blue fwBold marginR10 flex-none"> {{scope.index < 10 ?'0'+(scope.index+1):scope.index+1}} </text>
<text class="flex1 text-overflow c-text fs16">{{scope.row.title}}</text>
</view>
<text class="marginLR10 flex-none">{{scope.row.time}}</text>
</view>
</template>
<template slot="weight" slot-scope="scope">
<span>{{scope.row.weight}}{{scope.row.unit}}</span>
</template>
<template slot="status" slot-scope="scope">
<view class="w-flex row row-between paddingLR30 paddingTB10">
<u-tag text="待入库" mode="plain"/>
<view v-if="scope.row.status == 0" class="" style="color:#FF7D00">
<u-icon name="clock"></u-icon>
<text class="marginL10">未上报</text>
</view>
<view v-else class="" style="color:#00B42A">
<u-icon name="checkbox-mark"></u-icon>
<text class="marginL10">已上报</text>
</view>
</view>
</template>
<!-- 二维码 -->
<template slot="qrcode" slot-scope="scope">
<view class="w-flex">
<img class="width160 height160" src="/static/img/qrcode.png" alt="">
</view>
</template>
</w-table>
w-table组件源码
<template>
<view class="width w-table">
<view
v-if="tableData.length > 0"
class="w-flex col item-list marginB20 marginLR20 radius8 relative"
v-for="(item, index) in tableData"
:key="index">
<slot name="header" :row="item" :index="index"></slot>
<view class="width w-flex col paddingT15">
<!-- <u-read-more class="width" :toggle="true" closeText="更多" :showHeight="showHeight" color="#4E5969"> -->
<u-cell-group>
<template v-for="(cellItem,i) in propList">
<template v-if="!cellItem.formatItem">
<!-- 默认展示 show为true时 或者 不需要折叠时执行展示列 -->
<view class="default-show" v-if="cellItem.show || !toggle">
<u-cell-item :title="cellItem.label" :key="i" :arrow="false">
<slot v-if="typeof cellItem.formatValue === 'boolean' ? cellItem.formatValue : false"
:row="item" :name="cellItem.prop" :index="index"></slot>
<text v-else>{{$util.formatTextEmpty(item[cellItem.prop])}}</text>
</u-cell-item>
</view>
<!-- 默认不展示 -->
<view class="default-notshow" v-if="!cellItem.show && item.isShow">
<u-cell-item :title="cellItem.label" :key="i" :arrow="false">
<slot v-if="typeof cellItem.formatValue === 'boolean' ? cellItem.formatValue : false"
:row="item" :name="cellItem.prop" :index="index"></slot>
<text v-else>{{$util.formatTextEmpty(item[cellItem.prop])}}</text>
</u-cell-item>
</view>
</template>
<template v-if="cellItem.formatItem">
<!-- 整体插槽列默认展示 -->
<slot v-if="cellItem.show" :name="cellItem.prop" :row="item" :index="index"></slot>
<!-- 整体插槽列默认不展示 并且 列表展开时展示 -->
<slot v-if="!cellItem.show && item.isShow" :name="cellItem.prop" :row="item" :index="index"></slot>
</template>
</template>
<view v-show="toggle" class="width padding20 textCenter">
<span v-show="!item.isShow" @click="toggleCell(index,true)">更多<u-icon name="arrow-down" class="marginL5"></u-icon></span>
<span v-show="item.isShow" @click="toggleCell(index,false)">收起<u-icon name="arrow-up" class="marginL5"></u-icon></span>
</view>
</u-cell-group>
<!-- </u-read-more> -->
</view>
</view>
</view>
</template>
<script>
export default{
props:{
tableData:{
default:[],
type:Array,
},
propList:{
default:[],
type:Array,
},
showHeight:{
default:500,
type:Number,
},
toggle:{
default:true,
type:Boolean,
}
},
data(){
return{
}
},
mounted(){
if(this.toggle){
// 可以展开收起时,给表格默认增加isShow属性
this.tableData.forEach(item=>{
this.$set(item,'isShow',!this.toggle)
})
}else{
// 不需要收缩功能时,每一列数据默认是true,即展示,
// 也就是toggle为false时,propList设置show属性无效,均为true
this.propList.forEach(item=>{
this.$set(item,'show',!this.toggle)
})
}
},
methods:{
toggleCell(i,value){
this.$set(this.tableData[i],'isShow',value)
}
}
}
</script>
<style lang="scss" scoped>
::v-deep.u-cell{
align-items: flex-start;
}
::v-deep.u-cell-box{
text-indent: initial;
}
::v-deep.w-table .u-content__showmore-wrap{
background-image:none !important;
}
::v-deep.w-table .u-cell_title{
width: 90px !important;
flex: none;
font-size: 13px !important;
}
::v-deep.w-table .u-cell__value{
text-align: left !important;
overflow-wrap: break-word;
}
</style>