admin/addon/cashier/source/os/components/uni-data-table/uni-data-table.vue

251 lines
5.4 KiB
Vue

<template>
<view class="table-container">
<view class="thead">
<view class="th" v-for="(th, thIndex) in cols" :key="thIndex" :style="{flex: th.width, maxWidth: th.width + '%', textAlign: (th.align ? th.align : 'center')}">
<view class="content">
<view v-if="th.checkbox" class="iconfont" @click="all" :class="{
'iconfuxuankuang2': selected.length == 0,
'iconcheckbox_weiquanxuan': selected.length != list.length,
'iconfuxuankuang1': selected.length > 0 && selected.length == list.length
}"></view>
<text v-else>{{ th.title }}</text>
</view>
</view>
</view>
<view class="tbody">
<view class="tr" v-for="(d, index) in list" :key="index" v-if="list.length">
<view class="td" v-for="(th, thIndex) in cols" :key="thIndex" :style="{flex: th.width, maxWidth: th.width + '%', textAlign: (th.align ? th.align : 'center')}">
<view class="content" :class="{action:th.action}">
<view v-if="th.checkbox" @click="single(d, index)">
<view v-if="th.checkbox" class="iconfont" :class="{
'iconfuxuankuang2': selectedIndex.indexOf(index) == -1,
'iconfuxuankuang1': selectedIndex.indexOf(index) != -1
}"></view>
</view>
<slot v-else-if="th.action" name="action" :value="d" :index="index"></slot>
<text v-else-if="th.templet" v-html="th.templet(d)"></text>
<text v-else-if="th.return">{{ th.return(d) }}</text>
<text v-else>{{ d[ th.field ] }}</text>
</view>
</view>
</view>
<view class="tr empty" v-if="!list.length">
<view class="td">
<view class="iconfont iconwushuju"></view>
<view>暂无数据</view>
</view>
</view>
</view>
<view class="batch-action">
<slot name="batchaction" :value="selected"></slot>
</view>
<view class="tpage" v-if="list.length">
<uni-pagination :total="total" :showIcon="true" @change="pageChange" :pageSize="pagesize" :value="page"/>
</view>
</view>
</template>
<script>
export default {
name: 'uniDataTable',
props: {
cols: {
type: Array
},
url: {
type: String
},
pagesize: {
type: Number,
default: 10
},
option:{
type:Object,
default:function() {
return {}
}
}
},
created() {
this.load();
},
data(){
return {
list: [],
selected: [],
selectedIndex: [],
page: 1,
total: 0
}
},
methods:{
/**
* 全选
*/
all(){
if (this.list.length) {
if (this.selected.length == this.list.length) {
this.selected = [];
this.selectedIndex = [];
} else {
let selectedIndex = [],
selected = [];
this.list.forEach((item, index) => {
selectedIndex.push(index);
selected.push(item);
})
this.selectedIndex = selectedIndex;
this.selected = selected;
}
this.$emit('checkBox', this.selected);
}
},
/**
* 单选
* @param {Object} item
* @param {Object} index
*/
single(item, index){
let _index = this.selectedIndex.indexOf(index);
if (_index == -1) {
this.selectedIndex.push(index);
this.selected.push(item);
} else {
this.selectedIndex.splice(_index, 1);
this.selected.splice(_index, 1);
}
this.$emit('checkBox', this.selected);
},
/**
* 设置默认选中数据
*/
defaultSelectData(selected, selectedIndex){
this.selected = selected;
this.selectedIndex = selectedIndex;
},
pageChange(e){
this.page = e.current;
this.load();
},
load(option = {}){
let data = {
page: this.page,
page_size: this.pagesize
};
if(this.option) Object.assign(data, this.option)
if (option) Object.assign(data, option);
this.$api.sendRequest({
url: this.url,
data: data,
success: res => {
if (res.code >= 0) {
this.list = res.data.list;
this.total = res.data.count;
// this.selected = [];
// this.selectedIndex = [];
this.$emit('tableData', this.list);
} else {
this.$util.showToast({ title: res.message })
}
},
fail: () => {
this.$util.showToast({title: '请求失败'})
}
});
}
}
}
</script>
<style lang="scss">
.table-container {
width: 100%;
.iconcheckbox_weiquanxuan,.iconfuxuankuang1,.iconfuxuankuang2 {
color: $primary-color;
cursor: pointer;
font-size: .16rem;
transition: all .3s;
}
.iconfuxuankuang2 {
color: #E6E6E6;
&:hover {
color: $primary-color;
}
}
}
.thead {
display: flex;
width: 100%;
height: .5rem;
background: #F7F8FA;
align-items: center;
.th {
padding: 0 .1rem;
box-sizing: border-box;
.content {
white-space: nowrap;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
.tr {
display: flex;
border-bottom: .01rem solid #E6E6E6;
min-height: .5rem;
align-items: center;
transition: background-color .3s;
padding: .1rem 0;
box-sizing: border-box;
&:hover {
background: #f5f5f5;
}
.td {
padding: 0 .1rem;
box-sizing: border-box;
.content {
white-space: nowrap;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
}
&.empty {
justify-content: center;
.td {
text-align: center;
color: #909399;
.iconfont {
font-size: .25rem;
margin: .05rem;
}
}
}
}
.tpage {
padding: .1rem 0;
.uni-pagination {
justify-content: flex-end;
}
}
</style>