|
@@ -0,0 +1,782 @@
|
|
|
+<template>
|
|
|
+ <view class="z-table">
|
|
|
+ <view class="z-table-main" :style="compluteHeight">
|
|
|
+ <view v-if="!tableLoaded && (!tableData || !columns)" :class="['z-loading', {ztableLoading: tableShow}]">
|
|
|
+ <view class="z-loading-animate"></view>
|
|
|
+ </view>
|
|
|
+ <view class="z-table-container">
|
|
|
+ <view class="z-table-pack">
|
|
|
+ <view class="z-table-title">
|
|
|
+ <view class="z-table-title-item" :class="{ 'z-table-stick-side': stickSide && index == 0 }" :style="{ width: item.width ? item.width + 'rpx' : '200rpx' }"
|
|
|
+ v-for="(item, index) in columns" :key="index" @click="sort(item.key, index)">
|
|
|
+ <view v-if="showSelect && !singleSelect && index === 0" class="select-box" @click="doSelect(true)">
|
|
|
+ <view :class="['select-tip', {'selected': selectAll}]"></view>
|
|
|
+ </view>
|
|
|
+ <view :class="['z-table-col-text', {'text-left': titleTextAlign === 'left', 'text-center': titleTextAlign === 'center', 'text-right': titleTextAlign === 'right'}]">
|
|
|
+ <view v-html="getTitleText(item.title)"></view>
|
|
|
+ <view v-if="item.hasOwnProperty('key') && item.hasOwnProperty('sort') && tableData.length" class="sort">
|
|
|
+ <view class="up-arrow" :class="{ action: nowSortKey == item.key && sortType == 'asc' }"></view>
|
|
|
+ <view class="down-arrow" :class="{ action: nowSortKey == item.key && sortType == 'desc' }"></view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view v-if="tableData.length" :class="['table-container-box', {'short-table': !longTable && showBottomSum}]">
|
|
|
+ <view class="z-table-container-row" :class="{ 'z-table-has-bottom': showBottomSum }" v-for="(row, iIndex) in tableData"
|
|
|
+ :key="iIndex">
|
|
|
+ <view :class="['z-table-container-col', { 'z-table-stick-side': stickSide && jIndex == 0 }]" :style="{ width: col.width ? col.width + 'rpx' : '200rpx' }"
|
|
|
+ v-for="(col, jIndex) in columns" :key="jIndex" @click="itemClick(row, col)">
|
|
|
+ <view v-if="showSelect && jIndex === 0" class="select-box" @click="doSelect(false, iIndex)">
|
|
|
+ <view :class="['select-tip', {'selected': selectArr.includes(iIndex)}]"></view>
|
|
|
+ </view>
|
|
|
+ <view :class="['z-table-col-text', {'text-left': textAlign === 'left', 'text-center': textAlign === 'center', 'text-right': textAlign === 'right'}]">
|
|
|
+ <view v-if="!col.isLink" v-html="getRowContent(row, col)">
|
|
|
+ <!-- <view v-if="!col.render" v-html="getRowContent(row, col)"></view> -->
|
|
|
+ <!-- <renderComponents v-else :row="row" :col="col" /> -->
|
|
|
+ </view>
|
|
|
+ <!-- #ifdef H5 -->
|
|
|
+ <router-link v-else-if="setUrl(row, col).indexOf('http') != 0" :to="setUrl(row, col)" v-html="getRowContent(row, col)"></router-link>
|
|
|
+ <a v-else-if="col.isLink" :href="setUrl(row, col)" v-html="getRowContent(row, col)"></a>
|
|
|
+ <!-- #endif -->
|
|
|
+ <!-- #ifndef H5 -->
|
|
|
+ <navigator v-else-if="col.isLink" :url="setUrl(row, col)" v-html="getRowContent(row, col)"></navigator>
|
|
|
+ <!-- #endif -->
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view :class="['z-table-bottom', {'long-table': longTable}]" v-if="showBottomSum && tableData.length">
|
|
|
+ <view class="z-table-bottom-col" :class="{ 'z-table-stick-side': stickSide && sumIndex == 0 }" :style="{ width: sumCol.width ? sumCol.width + 'rpx' : '200rpx' }"
|
|
|
+ v-for="(sumCol, sumIndex) in columns" :key="sumIndex">
|
|
|
+ <view class="z-table-bottom-text">
|
|
|
+ <!-- <view v-if="sumIndex != 0" class="z-table-bottom-text-title">{{ sumCol.title }}</view> -->
|
|
|
+ <text :class="{ sum: sumIndex == 0 }">{{ sumIndex == 0 ? '总计' : dosum(sumCol.key) }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view v-if="tableData && tableData.length == 0 && !tableLoaded" class="table-empty">
|
|
|
+ <!-- image v-if="!showLoading" class="empty-img" src="../static/empty.png"></image -->
|
|
|
+ <view v-html="showLoading ? '' : emptyText"></view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ /*
|
|
|
+ * 表格使用
|
|
|
+ * 注意如果需要异步加载,需要把tableData初始值设为false,当没有数据的时候值为空数组
|
|
|
+ * props: tableData [Array | Boolean] | 表格数据 如果为false则显示loading
|
|
|
+ * columns [Array | Boolean] | 数据映射表 如果为false则显示loading 每列params => title(表头文字可以是html字符串模版), width(每列宽度) [, key(对应tableData的字段名) || format(自定义内容), sort(是否要排序), isLink(是否显示为超链接Object)]
|
|
|
+ * format格式: {template: 字符串模版用#key#表示需要被替换的数据,names: 对应template属性内要被替换的内容的key}
|
|
|
+ * isLink格式: {url: 链接地址, params: 地址带的参数Array[key|value, key|value, ...]每一项都是key和value以'|'链接,如果不带'|'默认键值同名
|
|
|
+ * listenerClick(是否监听点击事件Boolean)}
|
|
|
+ * stickSide Boolean | 是否固定右侧首栏 默认不显示
|
|
|
+ * showBottomSum Boolean | 是否显示底部统计 默认不显示
|
|
|
+ * showLoading Boolean | 是否首次加载首次加载不显示暂无数据内容
|
|
|
+ * emptyText String | 空数据显示的文字内容
|
|
|
+ * tableHeight Number | 设置表格高度会滚动
|
|
|
+ * sort Boolean | 开启排序
|
|
|
+ * showSelect Boolean | 开启选择
|
|
|
+ * singleSelect Boolean | 在开启选择的状态下是否开起单选
|
|
|
+ * textAlign String | 内容对齐方式 left center right
|
|
|
+ * titleTextAlign String | 表头对齐方式 left center right
|
|
|
+ *
|
|
|
+ * event: onSort | 排序事件 返回{key: 被排序列的字段名, type: 正序'asc'/倒序'desc'}
|
|
|
+ * onSelect | 选中时触发 返回选择的行的下标
|
|
|
+ * onClick | 单元格点击事件 返回点击单元格所属行的数据
|
|
|
+ *
|
|
|
+ * function: resetSort | 调用后重置排序 *注意:不会触发sort事件
|
|
|
+ *
|
|
|
+ * */
|
|
|
+ import Vue from 'vue'
|
|
|
+ // import tableRender from './table-render'
|
|
|
+
|
|
|
+ export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ version: '1.1.0',
|
|
|
+ nowSortKey: '',
|
|
|
+ sortType: 'desc', // asc/desc 升序/降序
|
|
|
+ longTable: true,
|
|
|
+ lineHeight: uni.upx2px(64),
|
|
|
+ tableLoaded: false,
|
|
|
+ tableShow: true,
|
|
|
+ selectAll: false,
|
|
|
+ selectArr: []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // mixin: [tableRender],
|
|
|
+ computed: {
|
|
|
+ compluteHeight() {
|
|
|
+ return this.tableHeight ?
|
|
|
+ 'height: ' + uni.upx2px(this.tableHeight) + 'px' :
|
|
|
+ ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ props: {
|
|
|
+ tableData: {
|
|
|
+ type: [Array, Boolean],
|
|
|
+ default () {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ columns: {
|
|
|
+ /*
|
|
|
+ *
|
|
|
+ * [{title: xxx, key: 当前列展示对象名, width: 列宽, render: function}]
|
|
|
+ *
|
|
|
+ * */
|
|
|
+ type: [Array, Boolean],
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ stickSide: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ showBottomSum: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ showLoading: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ emptyText: {
|
|
|
+ type: String,
|
|
|
+ default: '暂无数据'
|
|
|
+ },
|
|
|
+ tableHeight: {
|
|
|
+ type: [Number, Boolean],
|
|
|
+ default: 0
|
|
|
+ },
|
|
|
+ showSelect: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ singleSelect: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ textAlign: {
|
|
|
+ type: String,
|
|
|
+ default: 'left' // right|center|left
|
|
|
+ },
|
|
|
+ titleTextAlign: {
|
|
|
+ type: String,
|
|
|
+ default: 'left' // right|center|left
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.init()
|
|
|
+ },
|
|
|
+ // components: {
|
|
|
+ // renderComponents: {
|
|
|
+ // functional: true,
|
|
|
+ // props: {
|
|
|
+ // row: {
|
|
|
+ // type: Object,
|
|
|
+ // required: true
|
|
|
+ // },
|
|
|
+ // col: {
|
|
|
+ // type: Object,
|
|
|
+ // required: true
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+ // render: function(h, ctx) {
|
|
|
+ // return _this[ctx.props.col.render](h, ctx.props)
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+ watch: {
|
|
|
+ columns() {
|
|
|
+ this.init()
|
|
|
+ },
|
|
|
+ tableData() {
|
|
|
+ this.init()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ async init() {
|
|
|
+ // 重置选择内容
|
|
|
+ this.selectAll = false
|
|
|
+ this.selectArr = []
|
|
|
+ this.tableLoaded = false
|
|
|
+ this.tableShow = true
|
|
|
+ let _this = this
|
|
|
+ let container = await _this.getPageSize('.z-table-container'),
|
|
|
+ pack = await _this.getPageSize('.z-table-pack')
|
|
|
+ _this.timer && clearTimeout(_this.timer)
|
|
|
+ if (container && pack) {
|
|
|
+ _this.$nextTick(function() {
|
|
|
+ if (_this.tableData && _this.tableData.length) {
|
|
|
+ _this.tableShow = false
|
|
|
+ _this.timer = setTimeout(function() {
|
|
|
+ _this.tableLoaded = true
|
|
|
+ }, 300)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ if (container.height != pack.height) {
|
|
|
+ _this.longTable = true
|
|
|
+ } else {
|
|
|
+ _this.longTable = false
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ _this.tableLoaded = false
|
|
|
+ _this.$nextTick(function() {
|
|
|
+ _this.tableShow = true
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getPageSize(selecter) {
|
|
|
+ // 获取元素信息
|
|
|
+ let query = uni.createSelectorQuery().in(this),
|
|
|
+ _this = this
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ query
|
|
|
+ .select(selecter)
|
|
|
+ .boundingClientRect(res => {
|
|
|
+ resolve(res)
|
|
|
+ })
|
|
|
+ .exec()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ dosum(key) {
|
|
|
+ let sum = '-'
|
|
|
+ if (this.tableData) {
|
|
|
+ if (
|
|
|
+ this.tableData.every(item => {
|
|
|
+ return !Number.isNaN(item[key] - 0)
|
|
|
+ })
|
|
|
+ ) {
|
|
|
+ sum = 0
|
|
|
+ this.tableData.map((item, index) => {
|
|
|
+ if (!key && index != 0) {
|
|
|
+ sum = '-'
|
|
|
+ } else {
|
|
|
+ let val = item[key] - 0
|
|
|
+ if (Number.isNaN(val)) {
|
|
|
+ sum += 0
|
|
|
+ } else {
|
|
|
+ sum += val
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // sum = sum == 0 ? "-" : sum
|
|
|
+ return this.numTransform(sum)
|
|
|
+ },
|
|
|
+ getRowContent(row, col) {
|
|
|
+ // 表格值处理函数
|
|
|
+ // 如果columns带了key则显示对应的key
|
|
|
+ // 如果columns带的format则按规定返回format后的html
|
|
|
+ // format规定: params names <Array> 对应tableData的键名,作为匹配template中两个#之间动态内容的名字
|
|
|
+ // params template <String> html字符串模版
|
|
|
+ let tempHTML = ''
|
|
|
+ let rowKey = row[col.key]
|
|
|
+ if ([null, ''].includes(rowKey)) {
|
|
|
+ rowKey = '-'
|
|
|
+ }
|
|
|
+ if (rowKey || rowKey === 0) {
|
|
|
+ tempHTML = isNaN(rowKey - 0) ?
|
|
|
+ rowKey :
|
|
|
+ this.numTransform(rowKey - 0)
|
|
|
+ // tempHTML = tempHTML == 0 ? "-" : tempHTML
|
|
|
+ } else if (!!col.format) {
|
|
|
+ let tempFormat = col.format.template
|
|
|
+ col.format.names.map(item => {
|
|
|
+ let regexp = new RegExp(`\#${item}\#`, 'mg')
|
|
|
+ tempFormat = tempFormat.replace(regexp, row[item])
|
|
|
+ })
|
|
|
+ tempHTML = tempFormat
|
|
|
+ } else if (!col.render) {
|
|
|
+ let error = new Error('数据的key或format值至少一个不为空')
|
|
|
+ throw error
|
|
|
+ }
|
|
|
+ // console.log(tempHTML)
|
|
|
+ return tempHTML.toString()
|
|
|
+ },
|
|
|
+ sort(key, index) {
|
|
|
+ if (!key || !this.columns[index].sort) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 排序功能: 如果点击的排序按钮是原先的 那么更改排序类型
|
|
|
+ // 如果点击的另一个排序按钮 那么选择当前排序并且排序类型改为降序(desc)
|
|
|
+ if (key != this.nowSortKey) {
|
|
|
+ this.nowSortKey = key
|
|
|
+ this.sortType = 'desc'
|
|
|
+ } else {
|
|
|
+ this.toggleSort()
|
|
|
+ }
|
|
|
+ this.$emit('onSort', {
|
|
|
+ key: this.nowSortKey,
|
|
|
+ type: this.sortType
|
|
|
+ })
|
|
|
+ },
|
|
|
+ toggleSort() {
|
|
|
+ this.sortType = this.sortType == 'asc' ? 'desc' : 'asc'
|
|
|
+ },
|
|
|
+ numTransform(n) {
|
|
|
+ if (Number.isNaN(n - 0)) {
|
|
|
+ return n
|
|
|
+ }
|
|
|
+ if (Math.abs(n) >= 100000000) {
|
|
|
+ n = Number((n / 100000000).toFixed(1)) + '亿'
|
|
|
+ } else if (Math.abs(n) >= 10000) {
|
|
|
+ n = Number((n / 10000).toFixed(1)) + '万'
|
|
|
+ }
|
|
|
+ return n.toString()
|
|
|
+ },
|
|
|
+ resetSort() {
|
|
|
+ // 重置排序状态
|
|
|
+ this.nowSortKey = ''
|
|
|
+ this.sortType = 'desc'
|
|
|
+ },
|
|
|
+ setUrl(row, col) {
|
|
|
+ if (!col.isLink) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let urlParam = {}
|
|
|
+ let {
|
|
|
+ isLink: {
|
|
|
+ url,
|
|
|
+ params = []
|
|
|
+ }
|
|
|
+ } = col
|
|
|
+ params.forEach(item => {
|
|
|
+ if (~item.indexOf('|')) {
|
|
|
+ let temp = item.split('|')
|
|
|
+ urlParam[temp[0]] = row[temp[1]]
|
|
|
+ } else {
|
|
|
+ urlParam[item] = row[item]
|
|
|
+ }
|
|
|
+ })
|
|
|
+ url = this.setUrlParams(url, urlParam)
|
|
|
+ return url
|
|
|
+ },
|
|
|
+ setUrlParams(url, params) {
|
|
|
+ let tempUrl = url,
|
|
|
+ keyArr = Object.keys(params)
|
|
|
+ keyArr.forEach(item => {
|
|
|
+ tempUrl += `&${item}=${params[item]}`
|
|
|
+ })
|
|
|
+ tempUrl = tempUrl.replace(/\&/, '?')
|
|
|
+ return tempUrl
|
|
|
+ },
|
|
|
+ itemClick(row, col) {
|
|
|
+ if (col.listenerClick) {
|
|
|
+ this.$emit('onClick', row)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ doSelect(isAll = false, index) {
|
|
|
+ let temp = new Set()
|
|
|
+ if (isAll) {
|
|
|
+ // 全选
|
|
|
+ if (!this.selectAll) {
|
|
|
+ for (let i = 0; i < this.tableData.length; i++) {
|
|
|
+ temp.add(i)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // if (!this.singleSelect) {
|
|
|
+ // this.selectArr.forEach(item => {
|
|
|
+ // temp.add(item)
|
|
|
+ // })
|
|
|
+ // }
|
|
|
+ this.selectArr.forEach(item => {
|
|
|
+ temp.add(item)
|
|
|
+ })
|
|
|
+ if (temp.has(index)) {
|
|
|
+ temp.delete(index)
|
|
|
+ } else {
|
|
|
+ if (this.singleSelect) {
|
|
|
+ temp.clear()
|
|
|
+ }
|
|
|
+ temp.add(index)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.selectArr = Array.from(temp)
|
|
|
+ // console.log(this.selectArr)
|
|
|
+ if (this.selectArr.length == this.tableData.length) {
|
|
|
+ this.selectAll = true
|
|
|
+ } else {
|
|
|
+ this.selectAll = false
|
|
|
+ }
|
|
|
+
|
|
|
+ this.$emit('onSelect', this.selectArr)
|
|
|
+ },
|
|
|
+ // 1.1.1
|
|
|
+ getTitleText(title) {
|
|
|
+ // 自定义表头
|
|
|
+ let tempHTML = title
|
|
|
+ return tempHTML.toString()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+ .navigator-hover {
|
|
|
+ background: transparent;
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ @mixin ellipsis($num: 1) {
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+
|
|
|
+ @if $num==1 {
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ @else {
|
|
|
+ display: -webkit-box;
|
|
|
+ -webkit-line-clamp: $num;
|
|
|
+ /* autoprefixer: off */
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
+ /* autoprefixer: on */
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 三角形
|
|
|
+ %triangle-basic {
|
|
|
+ content: '';
|
|
|
+ height: 0;
|
|
|
+ width: 0;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ @mixin triangle($direction, $size, $borderColor) {
|
|
|
+ @extend %triangle-basic;
|
|
|
+
|
|
|
+ @if $direction==top {
|
|
|
+ border-bottom: $size solid $borderColor;
|
|
|
+ border-left: $size dashed transparent;
|
|
|
+ border-right: $size dashed transparent;
|
|
|
+ border-top: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ @else if $direction==right {
|
|
|
+ border-left: $size solid $borderColor;
|
|
|
+ border-top: $size dashed transparent;
|
|
|
+ border-bottom: $size dashed transparent;
|
|
|
+ border-right: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ @else if $direction==bottom {
|
|
|
+ border-top: $size solid $borderColor;
|
|
|
+ border-left: $size dashed transparent;
|
|
|
+ border-right: $size dashed transparent;
|
|
|
+ border-bottom: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ @else if $direction==left {
|
|
|
+ border-right: $size solid $borderColor;
|
|
|
+ border-top: $size dashed transparent;
|
|
|
+ border-bottom: $size dashed transparent;
|
|
|
+ border-left: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ a {
|
|
|
+ text-decoration: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-table {
|
|
|
+ position: relative;
|
|
|
+ display: inline-block;
|
|
|
+ height: 100%;
|
|
|
+ min-height: 130rpx;
|
|
|
+ width: 100%;
|
|
|
+ background: #fff;
|
|
|
+ border: solid 2rpx #ccc;
|
|
|
+ font-size: $uni-font-size-sm;
|
|
|
+ box-sizing: border-box;
|
|
|
+ transform: translateZ(0);
|
|
|
+
|
|
|
+ .z-table-main {
|
|
|
+ height: 100%;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-table-container {
|
|
|
+ height: 100%;
|
|
|
+ overflow: scroll;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-table-pack {
|
|
|
+ position: relative;
|
|
|
+ min-height: 100%;
|
|
|
+ width: fit-content;
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-table-title {
|
|
|
+ position: sticky;
|
|
|
+ top: 0;
|
|
|
+ height: 64rpx;
|
|
|
+ z-index: 1;
|
|
|
+
|
|
|
+ .z-table-title-item {
|
|
|
+ border-bottom: solid 1rpx #dbdbdb;
|
|
|
+ background: #f8f8f8;
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-table-stick-side {
|
|
|
+ position: sticky;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ border-right: solid 1rpx #dbdbdb;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .table-container-box.short-table {
|
|
|
+ padding-bottom: 48rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-table-title,
|
|
|
+ .z-table-container-row {
|
|
|
+ display: flex;
|
|
|
+ width: fit-content;
|
|
|
+ white-space: nowrap;
|
|
|
+ box-sizing: border-box;
|
|
|
+
|
|
|
+ .z-table-title-item,
|
|
|
+ .z-table-container-col {
|
|
|
+ @include ellipsis();
|
|
|
+ display: inline-flex;
|
|
|
+ padding: 0 16rpx;
|
|
|
+ height: 64rpx;
|
|
|
+ align-items: center;
|
|
|
+ line-height: 64rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-table-container-row {
|
|
|
+ z-index: 0;
|
|
|
+ border-bottom: solid 1rpx #f4f4f4;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-table-stick-side {
|
|
|
+ position: sticky;
|
|
|
+ left: 0;
|
|
|
+ background: #f7f9ff;
|
|
|
+ border-right: solid 1rpx #dbdbdb;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-table-bottom {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ z-index: 9;
|
|
|
+ display: flex;
|
|
|
+ justify-items: center;
|
|
|
+ width: fit-content;
|
|
|
+ background: #4298f7 !important;
|
|
|
+ color: #fff !important;
|
|
|
+ white-space: nowrap;
|
|
|
+ box-sizing: border-box;
|
|
|
+
|
|
|
+ &.long-table {
|
|
|
+ position: sticky;
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-table-stick-side {
|
|
|
+ background: #4298f7 !important;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-table-bottom-col {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ text-align: center;
|
|
|
+ padding: 16rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-table-bottom-text {
|
|
|
+ line-height: 100%;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-table-bottom-text-title {
|
|
|
+ margin-bottom: 10rpx;
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #aad0ff;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .sum {
|
|
|
+ margin-left: 14rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .table-empty {
|
|
|
+ position: absolute;
|
|
|
+ top: 64rpx;
|
|
|
+ height: 64rpx;
|
|
|
+ line-height: 64rpx;
|
|
|
+ width: 100%;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .sort {
|
|
|
+ display: flex;
|
|
|
+ padding: 5rpx;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+
|
|
|
+ .up-arrow {
|
|
|
+ @include triangle(top, 10rpx, #ccc);
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 5rpx;
|
|
|
+
|
|
|
+ &.action {
|
|
|
+ @include triangle(top, 10rpx, #4298f7);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .down-arrow {
|
|
|
+ @include triangle(bottom, 10rpx, #ccc);
|
|
|
+ display: block;
|
|
|
+
|
|
|
+ &.action {
|
|
|
+ @include triangle(bottom, 10rpx, #4298f7);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1.0.5
|
|
|
+ .z-loading {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ z-index: 2;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ height: 100%;
|
|
|
+ width: 100%;
|
|
|
+ background: #fff;
|
|
|
+ opacity: 0;
|
|
|
+ transition: all 0.3s;
|
|
|
+
|
|
|
+ &.ztableLoading {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .z-loading-animate {
|
|
|
+ position: relative;
|
|
|
+ display: inline-block;
|
|
|
+ width: 30rpx;
|
|
|
+ height: 30rpx;
|
|
|
+ margin-right: 20rpx;
|
|
|
+ border-radius: 100%;
|
|
|
+ border: solid 6rpx #ccc;
|
|
|
+ vertical-align: middle;
|
|
|
+ animation: rotate 1s ease-in-out infinite;
|
|
|
+
|
|
|
+ &::after {
|
|
|
+ content: '';
|
|
|
+ display: block;
|
|
|
+ position: absolute;
|
|
|
+ top: -10rpx;
|
|
|
+ z-index: 1;
|
|
|
+ background: #fff;
|
|
|
+ width: 20rpx;
|
|
|
+ height: 20rpx;
|
|
|
+ border-radius: 10rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes rotate {
|
|
|
+ from {
|
|
|
+ transform: rotate(0deg);
|
|
|
+ }
|
|
|
+
|
|
|
+ to {
|
|
|
+ transform: rotate(360deg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1.1.0
|
|
|
+ .select-box {
|
|
|
+ display: inline-block;
|
|
|
+ width: 26rpx;
|
|
|
+ height: 26rpx;
|
|
|
+ line-height: 14rpx;
|
|
|
+ margin-right: 15rpx;
|
|
|
+ border: solid 2rpx #4298f7;
|
|
|
+ border-radius: 4rpx;
|
|
|
+ background: #fff;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .select-tip {
|
|
|
+ display: inline-block;
|
|
|
+ opacity: 0;
|
|
|
+ transform: rotate(90deg);
|
|
|
+ transition: all .3s;
|
|
|
+
|
|
|
+ &.selected {
|
|
|
+ position: relative;
|
|
|
+ top: 4rpx;
|
|
|
+ left: -4rpx;
|
|
|
+ height: 4rpx;
|
|
|
+ background: #4298f7;
|
|
|
+ width: 10rpx;
|
|
|
+ opacity: 1;
|
|
|
+ transform: rotate(45deg);
|
|
|
+
|
|
|
+ &:before,
|
|
|
+ &:after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ display: block;
|
|
|
+ height: 4rpx;
|
|
|
+ background: #4298f7;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:before {
|
|
|
+ bottom: -2rpx;
|
|
|
+ left: -4rpx;
|
|
|
+ width: 8rpx;
|
|
|
+ transform: rotate(-90deg);
|
|
|
+ }
|
|
|
+
|
|
|
+ &:after {
|
|
|
+ bottom: 16rpx;
|
|
|
+ right: -16rpx;
|
|
|
+ width: 34rpx;
|
|
|
+ transform: rotate(-90deg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1.1.1
|
|
|
+ .z-table-col-text {
|
|
|
+ display: flex;
|
|
|
+ width: 100%;
|
|
|
+ flex: 1;
|
|
|
+ justify-content: flex-start;
|
|
|
+ align-content: center;
|
|
|
+
|
|
|
+ &.text-center {
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.text-right {
|
|
|
+ justify-content: flex-end;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|