前言:
由于最近需要做移動(dòng)端的項(xiàng)目
有個(gè)pc端的后臺(tái)系統(tǒng)里面需要移一部分頁面過來
而里面就有很多的表格,我就開始慣例網(wǎng)上先找前人栽的樹,我好乘涼
然后找了一圈發(fā)現(xiàn),不管是主流的移動(dòng)端ui庫或者網(wǎng)上自己寫的帖子,或者uniapp的插件網(wǎng)站
都沒有看到符合我要求的表格,然后如果要改別人的源碼那我看代碼都要看很久,好切有些還奇奇怪怪的bug不兼容
可能是別人使用了某些組件和插件之類的。導(dǎo)致我很多設(shè)置不生效。沒錯(cuò),我也改過別人的源碼了,后來放棄了。
所以我就直接手寫了一個(gè)簡(jiǎn)單的表格展示組件,配上一些我需要的功能。可以先用著了。
重點(diǎn)是我是原生的標(biāo)簽寫的,不是引入一大堆的插件之類的,uniapp可以直接用。
想修改源碼也簡(jiǎn)單。我都注釋好了
效果圖
小程序頁面兼容,可以看到點(diǎn)擊按鈕之后會(huì)拿到對(duì)應(yīng)行的數(shù)據(jù)
H5頁面的,也是一樣兼容的可能,也能拿到數(shù)據(jù)
移動(dòng)端,手機(jī)預(yù)覽效果,展示了數(shù)據(jù)和點(diǎn)擊生效,滾動(dòng)到底部可以觸發(fā)方法,可以在這里寫加載第二頁表格的方法
功能:
1,數(shù)據(jù)展示:只需要往組件內(nèi)傳入表頭和列表數(shù)據(jù)就能展示,列表數(shù)據(jù)和elementul的表格一樣。表頭要自己配置
2,固定表頭:上滾動(dòng)的時(shí)候表頭會(huì)定位在上面不動(dòng)
3,固定列:表頭內(nèi)配置屬性,可以讓這一列固定左邊不動(dòng)。目前只能固定一列
4,行底紋:就是給一行的單元格加上背景色,需要在tabledata列表中添加一個(gè)字段bgcolor就可以了
5,列底紋:同上,區(qū)別是在表頭內(nèi)添加一個(gè)字段bgcolor
6,單元格文字顏色改變:這是我們項(xiàng)目的要求,需要拿到每個(gè)單元格的數(shù)據(jù)和指標(biāo)對(duì)比大小來標(biāo)紅。這里在父組件就可以配置
7,操作列:表頭添加操作列,key給edit就會(huì)出現(xiàn)一個(gè)編輯和刪除的列。不寫就沒有這一列。點(diǎn)擊按鈕會(huì)觸發(fā)父組件的方法
8,滾動(dòng)到底部:滾動(dòng)到底部會(huì)觸發(fā)父組件方法??梢宰鰳I(yè)務(wù)操作,比如拿第二頁的表格
9,自動(dòng)列寬:根據(jù)表格內(nèi)單元格內(nèi)容的寬度來動(dòng)態(tài)賦值幾個(gè)寬度,寬度是提前定義好的。由于表頭和表體需要寬度一致,所以提前設(shè)置幾個(gè)檔次的固定寬度。具體使用是自動(dòng)根據(jù)表體或者表頭哪一個(gè)長,用哪一個(gè)的寬。保證數(shù)據(jù)的展示完全。當(dāng)數(shù)據(jù)過長的時(shí)候會(huì)自動(dòng)隱藏并省略號(hào)顯示。這里我就沒有加其他的功能了,后期可以自行更改,把這個(gè)文字加一個(gè)組件包裹,就是點(diǎn)擊可以顯示全部文字的彈框那個(gè)。
引入組件
uniapp可以直接使用,整體就引入了一個(gè)組件,uniapp帶有的scroll-view組件。需要去uniapp文檔內(nèi)引入一下,直接插件市場(chǎng)下載一下就好了
代碼:
組件部分:
寫一個(gè)tableDiv的vue文件,當(dāng)然名字隨便你換
然后把代碼復(fù)制進(jìn)去。
<template>
<view class="wrap">
<!-- @scrolltolower:滾動(dòng)到底部觸發(fā) lower-threshold:距離底部多少距離觸發(fā)@scrolltolower -->
<scroll-view class="scroll-view_H" scroll-x="true" scroll-y="true" @scrolltolower='scrollBottom'
:lower-threshold='2'>
<view class="top" id="top" :style="{width:tableWidths+'px'}">
<view v-for="(h,n) in header" :key='n' :class="{'header_dyg':true,'flexs':h.flxe}"
:style="{width:h.hWidth+'px'}">
{{h.name}}
</view>
</view>
<view class="bottom" :style="{maxHeight: tableHeight+'px',width:tableWidths+'px'}">
<view class="tablebox" v-for="(t,s) in tableData" :key='s' @click="jumpDetailed(t)">
<view v-for="(h,n) in header" :key="n"
:class="{'table_dyg':true,'tdColClass':h.bgcolor,'tdRowClass':t.bgcolor,'flexs':h.flxe}"
:style="{width:h.hWidth+'px'}">
<!-- 不等于操作列就顯示文字 -->
<text v-if="h.key!=='edit'" :style="{color:getColor(t,h)}">{{t[h.key]}}</text>
<!-- 操作列顯示按鈕,后期用插槽 -->
<view class="uni-group" v-else style="background-color: #fff;">
<button class="uni-button" size="mini" type="primary" style="margin-right: 5px;"
@click="editTable(t)">編輯</button>
<button class="uni-button" size="mini" type="warn" @click="deleteTable(t)">刪除</button>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
// 表頭配置:flxe(固定列),bgcolor(列底紋)
// 表體配置:bgcolor(行底紋)
export default {
props: {
data2: {
type: Array,
required: true,
default: function() {
return [];
}
},
head: {
type: Array,
required: true,
default: function() {
return [];
}
},
tableHeight: {
required: true,
type: [Number, String],
default: function() {
return 0;
}
}
},
data() {
return {
//表體
tableData: [],
//表頭
header: [],
// 表格總長度
tableWidths:0
}
},
watch:{
// 監(jiān)聽列表
'data2'(a,b){
this.tableData = a
},
// 監(jiān)聽表頭
'head'(a,b){
this.header = a
//計(jì)算列寬
this.tableWidth()
},
},
created() {
this.tableData = this.data2 //列表
this.header = this.head //表頭
this.tableWidth()
},
methods: {
// 返回行數(shù)據(jù)
jumpDetailed(row){
this.$emit('rowData',row)
},
// 滾動(dòng)到底部,調(diào)用父組件方法
scrollBottom(e) {
// 滾動(dòng)到底部才觸發(fā),滾動(dòng)到右邊不觸發(fā)
if (e.detail.direction == "bottom") {
this.$emit('scrollBottom')
}
},
// 顏色對(duì)比
getColor(row, col) {
let color = 'black'
// 傳值給父組件,通過父組件的方法內(nèi)計(jì)算判斷當(dāng)前單元格數(shù)據(jù)是否需要標(biāo)紅,然后通過回調(diào)函數(shù),返回一個(gè)color值來渲染
this.$emit('getTextColor', row, col, val => {
color = val
})
return color
},
// 修改按鈕
editTable(val) {
this.$emit('getEdit', val)
},
// 刪除按鈕
deleteTable(val) {
this.$emit('getDelete', val)
},
// 計(jì)算單元格寬度
tableWidth() {
let w=0 //計(jì)算表格長度
this.header.forEach((head, index) => {
let hw = head.name.length //表頭單元格寬度
let dw = 0 //列表單元格寬度
this.tableData.forEach(data => {
// 如果是操作列,就直接給十個(gè)字符長度,也就是列寬自動(dòng)150,不是操作列的統(tǒng)一看字符串長度決定寬度
let a = (head.key == 'edit' ? '1234567891' : (data[head.key]?data[head.key].toString():'1'))
let tw = (head.key == 'edit' ? 10 : a.length)
// 這里每次循環(huán)找出更大的數(shù)賦值,確保dw中是表體單元格這一列中最大寬度,根據(jù)最大寬度來判斷單元格顯示
if (dw < tw) {
dw = tw
}
})
// 表體單元格內(nèi)容寬度小于表頭內(nèi)容時(shí),以表頭的寬度為主。根據(jù)表頭的字符長度來區(qū)分寬度
if (dw <= hw) {
if (hw <= 3) {
head['hWidth'] = 50
} else if (hw <= 5) {
head['hWidth'] = 80
} else {
head['hWidth'] = 130
}
} else {
// 表體內(nèi)容寬度大于表頭內(nèi)容寬度時(shí),以表體寬度為主。根據(jù)表頭的字符長度來區(qū)分寬度
if (dw <= 3) {
head['hWidth'] = 50
} else if (dw <= 5) {
head['hWidth'] = 80
} else {
head['hWidth'] = 130
}
}
w+=head['hWidth'] //疊加表格總長度
})
this.tableWidths=w //給表格賦值總長度
}
}
}
</script>
<style lang="scss">
.wrap {
width: 100%;
}
// 表頭
.top {
display: flex;
position: sticky; //表頭向上滾動(dòng)時(shí)固定住
top: 0;
//width: 750px; //左右滾動(dòng)時(shí)不會(huì)把固定的表頭滾動(dòng)走
z-index: 100; //滑動(dòng)時(shí)表頭不被覆蓋
.header_dyg {
height: 40px;
text-align: center;
line-height: 40px;
border-top: 1px solid #ccc;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
padding: 0 5px;
background-color: #f5f5f6;
font-size: 14px;
font-weight: bold;
color: #2b2b2b;
flex-shrink: 0;
}
// 列定位固定單元格
.flexs {
position: sticky;
left: 0;
background-color: #f5f5f6;
z-index: 10;
}
}
// 表格列表
.bottom {
//width: 750px;
.tablebox {
display: flex;
font-size: 14px;
.table_dyg {
height: 30px;
text-align: center;
line-height: 30px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
padding: 0 5px;
flex-shrink: 0;
}
// 列定位固定單元格
.flexs {
position: sticky;
left: 0;
background-color: #fff;
z-index: 10;
}
}
}
// 列的顏色
.tdColClass {
background-color: #d9edf7;
}
// 行的顏色
.tdRowClass {
background-color: #afdfe4;
}
</style>
然后父組件引入子組件使用文章來源:http://www.zghlxwxcb.cn/news/detail-782297.html
<template>
<view class="box">
<!-- 表格組件:參數(shù)解釋:@getTextColor:調(diào)用方法判斷數(shù)據(jù)后返回對(duì)比顏色,可以改變單元格文字的顏色 -->
<!-- @getEdit:點(diǎn)擊表格中編輯按鈕會(huì)觸發(fā)的方法 @getDelete:點(diǎn)擊表格中刪除按鈕會(huì)觸發(fā)的方法 @scrollBottom:滾動(dòng)到底部時(shí)觸發(fā) @rowData:獲取點(diǎn)擊行的數(shù)據(jù)-->
<!-- data:列表數(shù)據(jù),格式和elementul表格一樣,head:表頭數(shù)據(jù),格式[{name:'列名',key:'對(duì)應(yīng)列表的key',bgcolor:1代表這一列添加背景色,flxe:1代表這一列固定}],tableHeight:表格表體高度 -->
<tableDiv @scrollBottom='scrollBottom' @getTextColor='getRedText' @getEdit='editTable'
@getDelete='deleteTable' @rowData='getRow' :data2='tableData' :head='header' :tableHeight='310'>
</tableDiv>
</view>
</template>
<script>
import tableDiv from './tableDiv.vue'
export default {
components: {
tableDiv
},
data() {
return {
//表體
tableData: [{
"date": "2020-09-01",
"name": "11",
"address": "上海市普陀區(qū)金沙江路 1518 弄",
"age": "18",
bgcolor: 1
}, {
"date": "2020-09-02",
"name": "22",
"address": "上海市普陀區(qū)金沙江路 1517 弄",
"age": "18"
}, {
"date": "2020-09-03",
"name": "33",
"address": "上海市普陀區(qū)金沙江路 1519 弄",
"age": "18"
}, {
"date": "2020-09-04",
"name": "44",
"address": "上海市普陀區(qū)金沙江路 1516 弄",
"age": "18"
}, {
"date": "2020-09-05",
"name": "55",
"address": "上海市普陀區(qū)金沙江路 1518 弄",
"age": "18"
}, {
"date": "2020-09-06",
"name": "66",
"address": "上海市普陀區(qū)金沙江路 1517 弄",
"age": "18"
}, {
"date": "2020-09-06",
"name": "66",
"address": "上海市普陀區(qū)金沙江路 1517 弄",
"age": "18"
}, {
"date": "2020-09-06",
"name": "66",
"address": "上海市普陀區(qū)金沙江路 1517 弄",
"age": "18"
}, {
"date": "2020-09-06",
"name": "66",
"address": "上海市普陀區(qū)金沙江路 1517 弄",
"age": "18"
}, {
"date": "2020-09-06",
"name": "66",
"address": "上海市普陀區(qū)金沙江路 1517 弄",
"age": "18"
}, {
"date": "2020-09-06",
"name": "66",
"address": "上海市普陀區(qū)金沙江路 1517 弄",
"age": "18"
}, {
"date": "2020-09-06",
"name": "66",
"address": "上海市普陀區(qū)金沙江路 1517 弄",
"age": "18"
}, {
"date": "2020-09-06",
"name": "66",
"address": "上海市普陀區(qū)金沙江路 1517 弄",
"age": "18"
}],
//表頭
header: [{
name: '日期',
key: 'date',
flxe: 1 //固定的列,只能有一個(gè)列
}, {
name: '姓名',
key: 'name',
bgcolor: 1 //列底紋
}, {
name: '地址',
key: 'address'
}, {
name: '年齡',
key: 'age'
}, {
name: '年齡',
key: 'age'
}, {
name: '操作',
key: 'edit'
}]
}
},
methods: {
// 自定義事件方法,業(yè)務(wù)邏輯判斷是否需要標(biāo)紅,然后回調(diào)給子組件顏色
getRedText(row, col, callback) {
let color = 'black'
// 判斷值是否需要標(biāo)紅
if (row[col.key] == '22') {
color = 'red'
} else {
color = 'black'
}
// 通過回調(diào)函數(shù)返回值
callback(color);
},
// 編輯按鈕
editTable(val){
console.log(val,'編輯');
uni.showToast({
title: val.date+'編輯'
})
},
// 刪除按鈕
deleteTable(val){
console.log(val,'刪除');
uni.showToast({
title: val.date+'刪除'
})
},
// 滾動(dòng)到底部
scrollBottom(){
uni.showToast({
title: '滾動(dòng)到底部了'
})
console.log('滾動(dòng)到底部了');
},
//獲取行的數(shù)據(jù)
getRow(row){
}
}
}
</script>
<style lang="scss">
</style>
注意點(diǎn):
由于小程序不支持直接vue那種父子組件傳參形式。拿不到數(shù)據(jù),所以這里需要用watch監(jiān)聽一下props變化及時(shí)更新子組件。
H5頁面是可以支持vue的原本寫法的。直接進(jìn)來拿props就可以使用了。所以這里直接created內(nèi)賦值一下就可以了文章來源地址http://www.zghlxwxcb.cn/news/detail-782297.html
到了這里,關(guān)于【移動(dòng)端表格組件】uniapp簡(jiǎn)單實(shí)現(xiàn)H5,小程序,APP多端兼容表格功能,復(fù)制即用,簡(jiǎn)單易懂【詳細(xì)注釋版本】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!