【uniapp】通用列表封装组件

uniapp页面一般都会有像以下的列表页面,封装通用组件,提高开发效率;
(基于uView前端框架)
【uniapp】通用列表封装组件_第1张图片

首先,通过设计图来分析一下页面展示和数据结构定义

【uniapp】通用列表封装组件_第2张图片

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 列表收起时默认展示,toggletrue时生效 string true|false false
formatItem 整体列插槽(例如上图俩个状态按钮列,不展示左边标题名称,则需要整体插槽实现) boolean true|false false
formatValue 值插槽(例如返回值需要加单位,格式化等情况)
formatItemtrue时此属性不生效
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-cell-group>
						<template v-for="(cellItem,i) in propList">
							<template v-if="!cellItem.formatItem">
								
								<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>
				
			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>

你可能感兴趣的:(uni-app,服务器)