first commit

This commit is contained in:
zouzhibing
2022-03-02 10:56:22 +08:00
commit 9353e2d74c
15 changed files with 1247 additions and 0 deletions

24
.hbuilderx/launch.json Normal file
View File

@@ -0,0 +1,24 @@
{ // launch.json 配置了启动调试时相关设置configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtype项可配置值为local或remote, local代表前端连本地云函数remote代表前端连云端云函数
"version": "0.0",
"configurations": [{
"app-plus" :
{
"launchtype" : "local"
},
"default" :
{
"launchtype" : "local"
},
"mp-alipay" :
{
"launchtype" : "local"
},
"mp-weixin" :
{
"launchtype" : "local"
},
"type" : "uniCloud"
}
]
}

5
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,5 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/zzb-table.iml" filepath="$PROJECT_DIR$/.idea/zzb-table.iml" />
</modules>
</component>
</project>

12
.idea/zzb-table.iml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

29
App.vue Normal file
View File

@@ -0,0 +1,29 @@
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style>
/*每个页面公共css */
scroll-view ::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
//第二种
::-webkit-scrollbar{
display: none;
}
</style>

View File

@@ -0,0 +1,321 @@
<template>
<view :class="['zb-table','zb-table-fixed-header',(bodyTableLeft>50||headerTableLeft>50)&&'scroll-left-fixed']">
<view class="zb-table-content">
<view class="zb-table-scroll" style="height: 100%;">
<view class="zb-table-header top-header-uni" style="height: 40px;">
<scroll-view class="zb-table-headers"
@scroll="handleTableScrollLeft"
scroll-x="true"
scroll-y="true"
id="tableHeaders"
scroll-anchoring="true"
:scroll-left="headerTableLeft"
style="min-width: 17px;padding-bottom: 0px;
background: #fafafa;height: 100%">
<view class="zb-table-fixed" >
<view class="zb-table-thead" style="position: relative;" >
<view class="item-tr">
<view
@click="sortAction(item,index)"
:class="['item-th',item.sorter&&`sorting${item.sorterMode||''}`]"
:style="{
flex:index===transColumns.length-1?1:'none',
minWidth:'100px'
}"
v-for="(item,index) in transColumns" :key="index">{{ item.label }}</view>
</view>
</view>
</view>
</scroll-view>
</view>
<scroll-view class="zb-table-body"
ref="tableBody"
scroll-x="true"
scroll-y="true"
id="tableBody"
@scrolltoupper="scrollToLeft"
@scroll="handleBodyScroll"
:scroll-left="bodyTableLeft"
:scroll-top="bodyScrollTop"
style=" height: calc(100% - 50px);" >
<view class="zb-table-fixed">
<view class="zb-table-tbody">
<view class="item-tr" v-for="(item,index) in data">
<view
:style="{
flex:i===transColumns.length-1?1:'none',
minWidth:'100px'
}"
class="item-td"
v-for="(ite,i) in transColumns">{{ item[ite.name] }}</view>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="zb-table-fixed-left" v-if="isFixedLeft">
<view class="zb-table-header" style="height: 40px;">
<view class="item-tr" style="flex-direction: column;">
<view
@click="sortAction(transColumns[0],0)"
:class="['item-th',transColumns[0].sorter&&`sorting${transColumns[0].sorterMode||''}`]"
>{{ transColumns[0].label }}</view>
</view>
</view>
<view class="zb-table-body-outer center-header-uni" style="height: 100%;">
<scroll-view
scroll-y="true"
id="leftTableFixed"
@scroll="leftFixedScrollAction"
:scroll-top="leftFiexScrollTop"
class="zb-table-body-inner"
style=" height: calc(100% - 50px);">
<view class="zb-table-fixed">
<view class="zb-table-tbody">
<view class="item-tr"
style="flex-direction: column;">
<view class="item-td" v-for="item in data">{{item[transColumns[0].name]}}</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
</template>
<script>
import {toLocaleString} from '@/utils/index.js'
export default {
props:{
itemDate:{
type:Object,
default:()=>{}
},
columns:{
type:Array,
default:()=>[]
},
data:{
type:Array,
default:()=>[]
}
},
computed:{
isFixedLeft(){
if(!this.columns.length){
return false
}
let [firstArr] = this.columns
return !!firstArr.fixed;
},
transColumns(){
return this.columns
}
},
data() {
return {
bodyTableLeft:0,
headerTableLeft:0,
lastScrollLeft:0,
leftFiexScrollTop:0,
bodyScrollTop:0,
currentDriver:null,
currentDriver1:null,
bodyTime:null,
bodyTime1:null,
headerTime:null,
}
},
mounted(){
},
methods: {
//验证字符串是否是数字
checkNumber(theObj) {
var reg = /^[0-9]+.?[0-9]*$/;
if (reg.test(theObj)) {
return true;
}
return false;
},
isDate(data){
if(isNaN(data)&&!isNaN(Date.parse(data))){
return true
}
return false
},
sortAction(item,index){
this.$set(item,'sorterMode',item.sorterMode==='_asc'?'_desc':'_asc')
this.sortData(item)
},
sortData(item){
console.log('item===',item)
let key = item.name
if(item.sorterMode==='_asc'){
this.data.sort((a,b)=>{
if(this.checkNumber(a[key])){
return a[key]-b[key]
}
if(this.isDate(a[key])){
let a1 = new Date(a[key]).getTime()
let b1 = new Date(b[key]).getTime()
return a1-b1
}
})
}else {
this.data.sort((a,b)=>{
if(this.checkNumber(a[key])){
return b[key]-a[key]
}
if(this.isDate(a[key])){
let a1 = new Date(a[key]).getTime()
let b1 = new Date(b[key]).getTime()
return b1-a1
}
})
}
},
handleBodyScroll(e){
if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
this.currentDriver = e.currentTarget.id
this.headerTableLeft = e.detail.scrollLeft
this.leftFiexScrollTop = e.detail.scrollTop
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver=null
},200)
},
leftFixedScrollAction(e){
if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
this.currentDriver = e.currentTarget.id
this.bodyScrollTop = e.detail.scrollTop
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver=null
},200)
},
scrollToLeft(e){
if(e.detail.direction==='left'){
this.headerTableLeft = 0
}else if(e.detail.direction==='top'){
this.leftFiexScrollTop = 0
}
},
handleTableScrollLeft(e,type){
if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
this.currentDriver = e.currentTarget.id
this.bodyTableLeft = e.detail.scrollLeft
this.bodyTime&&clearTimeout(this.bodyTime)
this.bodyTime = setTimeout(()=>{
this.currentDriver=null
},200)
}
}
}
</script>
<style lang="scss" scoped>
.zb-table-content{
height: 100%;
position: relative;
}
.zb-table-fixed{
min-width: 100%;
}
.zb-table{
height: 100%;
overflow: hidden;
width: 100%;
font-size: 12px;
}
.sorting{
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjczRkE5Qjk2OTQwNDExRTk4NUU3RUY3OTQwOUYzOUU3IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjczRkE5Qjk3OTQwNDExRTk4NUU3RUY3OTQwOUYzOUU3Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NzNGQTlCOTQ5NDA0MTFFOTg1RTdFRjc5NDA5RjM5RTciIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NzNGQTlCOTU5NDA0MTFFOTg1RTdFRjc5NDA5RjM5RTciLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4R7rKqAAAAWklEQVR42mL8//8/AzUBEwOVwaiB2MHdu3f/gzBVDEQ2iBhDmYg1jFhDmUgxjBg5xkGfsFnI8RYIKCsrM5LkQlwaCMkxkeoKfIYRFYbIBhAybGjE8gg0ECDAAI+ULEsz8LFkAAAAAElFTkSuQmCC);
background-repeat: no-repeat;
background-position: center right;
background-size: 20px 20px;
cursor: pointer;
}
.sorting_asc{
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjlDMzQ5NTk4OTQwNDExRTk4ODYwRkRDNTNBRUE5MTc1IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjlDMzQ5NTk5OTQwNDExRTk4ODYwRkRDNTNBRUE5MTc1Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OUMzNDk1OTY5NDA0MTFFOTg4NjBGREM1M0FFQTkxNzUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OUMzNDk1OTc5NDA0MTFFOTg4NjBGREM1M0FFQTkxNzUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4u6TUfAAAAdElEQVR42mL8//8/AzUBEwOVweA3kIVUDdJbp8LZT72zyXMh0JD/IIzLEJIMhBmEzMZnKCO+ZINsGDIAGshIsgtxGUZIjnHQJ2ycyebu3bt4na6srMxIkgtxaSAkx0SqK/AZRlQYIhtAyLChEcsj0ECAAAMABS4rJ0ADXJ8AAAAASUVORK5CYII=);
background-repeat: no-repeat;
background-position: center right;
background-size: 20px 20px;
cursor: pointer;
}
.sorting_desc{
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjg1MjMyQjFCOTQwNDExRTk5NjhDQjc2MEYxQzUxNkEzIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjg1MjMyQjFDOTQwNDExRTk5NjhDQjc2MEYxQzUxNkEzIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6ODUyMzJCMTk5NDA0MTFFOTk2OENCNzYwRjFDNTE2QTMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6ODUyMzJCMUE5NDA0MTFFOTk2OENCNzYwRjFDNTE2QTMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz69xJt+AAAAaElEQVR42mL8//8/AzUBEwOVwaiB2MHdu3f/gzBVDEQ2iBhDmYg1jFhDmUgxjBg5xkGfsFlwSUhvnYrX6U+9sxlJciEuDYTkmEh1BUwM6APywhDZUHwuIxiG+FyKy3VDI9kMfgMBAgwAP+E336XXjQcAAAAASUVORK5CYII=);
background-repeat: no-repeat;
background-position: center right;
background-size: 20px 20px;
cursor: pointer;
}
.zb-table-body{
position: relative;
background: #fff;
transition: opacity 0.3s;
}
.item-tr{
display: flex;
}
.item-td{
flex-shrink: 0;
width: 100px;
padding-left: 8px;
height: 40px;
line-height: 40px;
box-sizing: border-box;
overflow-wrap: break-word;
border-bottom: 1px solid #e8e8e8;
transition: background 0.3s;
}
.item-th{
flex-shrink: 0;
width: 100px;
overflow-wrap: break-word;
border-bottom: 1px solid #e8e8e8;
transition: background 0.3s;
}
.zb-table-fixed-left .zb-table-header{
overflow-y: hidden;
}
.zb-table-header {
overflow: hidden;
background: #fafafa;
.item-th{
padding-left: 8px;
line-height: 39px;
height: 40px;
box-sizing: border-box;
}
}
.zb-table-fixed-left .zb-table-fixed{
background: #fff;
}
.zb-table-fixed-right .zb-table-fixed{
background: #fff;
}
.zb-table-fixed-header .zb-table-body-inner{
height: 100%;
// overflow: scroll;
}
.zb-table-fixed-left{
position: absolute;
top: 0;
z-index: 1;
overflow: hidden;
border-radius: 0;
height: 100%;
transition: box-shadow 0.3s ease;
}
.scroll-left-fixed{
.zb-table-fixed-left {
left: 0;
box-shadow: 6px 0 6px -4px #ccc;
}
}
</style>

20
index.html Normal file
View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

21
main.js Normal file
View File

@@ -0,0 +1,21 @@
import App from './App'
// #ifndef VUE3
import Vue from 'vue'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
// #endif

72
manifest.json Normal file
View File

@@ -0,0 +1,72 @@
{
"name" : "zzb-table",
"appid" : "__UNI__7F24098",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* */
"modules" : {},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios" : {},
/* SDK */
"sdkConfigs" : {}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2"
}

28
pages.json Normal file
View File

@@ -0,0 +1,28 @@
{
"pages": [ //pages数组中第一项表示应用启动页参考https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"condition" : { //模式配置,仅开发期间生效
"current": 0, //当前激活的模式(list 的索引项)
"list": [
{
"name": "", //模式名称
"path": "", //启动页面,必选
"query": "" //启动参数在页面的onLoad函数里面得到
}
]
}
}

129
pages/index/index.vue Normal file
View File

@@ -0,0 +1,129 @@
<template>
<view class="content">
<zb-table :columns="column" :data="data"></zb-table>
</view>
</template>
<script>
import ZbTable from '@/components/zb-table/index.vue'
export default {
components:{
ZbTable
},
data() {
return {
title: 'Hello',
column:[
{ name: 'name', label: '姓名',fixed:true },
{ name: 'age', label: '年纪',sorter:true },
{ name: 'sex', label: '性别' },
{ name: 'address', label: '地址' },
{ name: 'date', label: '日期',sorter:true },
{ name: 'province', label: '省份' },
{ name: 'city', label: '城市' },
{ name: 'zip', label: '邮编' },
],
data:[
{
date: '2016-05-02',
name: '王小虎1',
province: '上海',
sex:'男',
age:'16',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-05-01',
name: '王小虎2',
province: '上海',
sex:'男',
age:12,
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-05-02',
name: '王小虎3',
province: '上海',
sex:'男',
age:'15',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-04-02',
name: '王小虎4',
province: '上海',
sex:'男',
age:'11',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-03-02',
name: '王小虎5',
province: '上海',
sex:'男',
age:'14',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2014-05-02',
name: '王小虎6',
province: '上海',
sex:'男',
age:'12',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2019-05-02',
name: '王小虎7',
province: '上海',
sex:'男',
age:'10',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2012-05-02',
name: '王小虎8',
province: '上海',
sex:'男',
age:'29',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2011-05-02',
name: '王小虎9',
province: '上海',
sex:'男',
age:'30',
city: '普陀区',
address: '上海市普',
zip: 200333
}
]
}
},
onLoad() {
},
methods: {
}
}
</script>
<style>
.content{
height: 600rpx;
}
</style>

117
readme.md Normal file
View File

@@ -0,0 +1,117 @@
## 介绍
基于uni-app开发的一个普通的表格组件 ,功能有固定首列和表头,已用于生产环境
## column 属性
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| ------ | ------ | ------ | ------ | ------ |
| name | 属性值 | string |-- | -- |
| label | 显示的标题 | string |-- | -- |
| fixed | 列是否固定在左侧true 表示固定在左侧 | boolean |true,false | -- |
| sorter | 排序 | boolean |true,false | -- |
## 数据格式
```
column:[
{ name: 'name', label: '姓名',fixed:true },
{ name: 'age', label: '年纪' },
{ name: 'sex', label: '性别' },
{ name: 'address', label: '地址' },
{ name: 'date', label: '日期' },
{ name: 'province', label: '省份' },
{ name: 'city', label: '城市' },
{ name: 'zip', label: '邮编' },
],
data:[
{
date: '2016-05-02',
name: '王小虎1',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-05-02',
name: '王小虎2',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-05-02',
name: '王小虎3',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-05-02',
name: '王小虎4',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
},
{
date: '2016-05-02',
name: '王小虎5',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2016-05-02',
name: '王小虎6',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2016-05-02',
name: '王小虎7',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2016-05-02',
name: '王小虎8',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
},{
date: '2016-05-02',
name: '王小虎9',
province: '上海',
sex:'男',
age:'18',
city: '普陀区',
address: '上海市普',
zip: 200333
}
]
```

BIN
static/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

76
uni.scss Normal file
View File

@@ -0,0 +1,76 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场https://ext.dcloud.net.cn上很多三方插件均使用了这些样式变量
* 如果你是插件开发者建议你使用scss预处理并在插件代码中直接使用这些变量无需 import 这个文件方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者插件使用者你可以通过修改这些变量来定制自己的插件主题实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
/* 边框颜色 */
$uni-border-color:#c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16;
/* 图片尺寸 */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:20px;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:15px;

385
utils/index.js Normal file
View File

@@ -0,0 +1,385 @@
var funProto = Function.prototype;
var objProto = Object.prototype;
var getPrototypeOf = Object.getPrototypeOf;
var objToString = objProto.toString;
var hasOwnProperty = objProto.hasOwnProperty;
var funToString = funProto.toString;
// 获取 url 参数集合
export const getUrlParams = function (url) {
url = url || window.location.href;
var index = url.indexOf("?");
var result = {};
if(index !== -1){
var str = url.substr(index + 1, url.length - index - 1);
var parts = str.split("&");
for(var i = 0, length = parts.length; i < length; i++){
var part = parts[i];
var item = part.split("=");
var key = item[0];
var value = item[1];
result[key] = decodeURIComponent(value);
}
}
return result;
}
export const setTitle = (title)=>{
// #ifdef H5
// document.title=title
uni.setNavigationBarTitle({
title,
});
// console.log('===========ssss',title)
// #endif
// #ifndef H5
uni.setNavigationBarTitle({
title,
});
// #endif
}
export const decimalPlaces = (num)=>{
let newNum = num.toString().split('.')[1]
if(newNum&&newNum.length>2){
return num.toFixed(2)
}else {
return num
}
}
export const formatYAxisNumber = (num)=>{
if(num>1000000){
return decimalPlaces((num/1000000)) + '百万';
}else if(num>10000){
return decimalPlaces((num/10000)) + '万';
}else if(num>1000){
return decimalPlaces((num/1000)) + '千';
}else {
return decimalPlaces(num)
}
}
// // 深度克隆 array 数组或 json 对象,返回克隆后的副本
export const deepClone = function(obj){
let weakMap = new WeakMap()
function clone (obj){
if(!isArray(obj) && !isPlainObject(obj)){
return obj;
}
if(obj instanceof Date){ return new Date(obj) }
if(obj instanceof RegExp){ return new RegExp(obj)}
if(weakMap.get(obj)){
return weakMap.get(obj)
}
// var copy = utils.isArray(obj) ? [] : {};
var copy = new obj.constructor
weakMap.set(obj,copy)
for(var key in obj){
if(hasOwnProperty.call(obj, key)){
var value = obj[key];
copy[key] = clone(value);
}
}
return copy;
}
return clone (obj)
};
/**
* 获取不含子菜单的第一个菜单项
* @param {Array} data 菜单数据
*/
export const getMenuWithoutChildren = function (data){
var target;
for(var i = 0, length = data.length; i < length; i++){
var element = data[i];
if(element.children){
target = getMenuWithoutChildren(element.children);
}
else{
target = element;
}
if(target){
break;
}
}
console.log('target',target)
return target;
}
/**
*
*/
export const getChildrenMenu = function (data) {
var target = data[0]||{};
let arr = [target]
function deep(){
if(target.children){
target = target.children[0]
arr.push(target)
deep()
}
}
deep()
if(arr.length===1){
let item = arr[0]
item.isFlop = 1 // 是否是翻牌器
return [item];
}else{
let item = arr[arr.length-2]
item.children1 = item.children
item.isFlop = 1 // 是否是翻牌器
delete item.children
return item.children1;
}
}
/**
* 将英文字段名称转为中文标题
* @param {Array} columns 字段配置
* @param {String} name 英文字段名称
*/
export const getChartLegend = function(columns, name){
try{
columns = JSON.parse(columns);
var column = columns.find(function(column){
return column.dataIndex === name;
});
return column && column.title ? column.title : name;
}
catch(e){
return name;
}
};
export const debounce = function(fn, delay) {
// 定时器
let timer = null
// 将debounce处理结果当作函数返回
return function () {
// 保留调用时的this上下文
let context = this
// 保留调用时传入的参数
let args = arguments
// 每次事件被触发时,都去清除之前的旧定时器
if(timer) {
clearTimeout(timer)
}
// 设立新定时器
timer = setTimeout(function () {
fn.apply(context, args)
}, delay)
}
}
export const throttle = function(fn, interval) {
// last为上一次触发回调的时间
let last = 0
// 将throttle处理结果当作函数返回
return function() {
// 保留调用时的this上下文
let context = this
// 保留调用时传入的参数
let args = arguments
// 记录本次触发回调的时间
let now = +new Date()
// 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值
if (now - last >= interval) {
// 如果时间间隔大于我们设定的时间间隔阈值,则执行回调
last = now;
fn.apply(context, args);
}
}
}
// 检查给定的值是否是数值
export const isNumber = function (value) {
return objToString.call(value) === "[object Number]";
};
export const toLocaleString = function(value, toFixed){
if(!isNumber(value)){
return value;
}
if(toFixed){
value = value.toFixed(toFixed);
value = value.split(".");
var integer = value[0];
var decimal = value[1];
integer = String(integer).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return integer + "." + decimal;
}
else{
return String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
};
// 判断日期、时间、日期时间格式
export const check = {
date: function(value){
return /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/.test(value);
},
time: function(value){
return /^(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d$/.test(value);
},
datetime: function(value){
return /^[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\s+(20|21|22|23|[0-1]\d):[0-5]\d:[0-5]\d(.0)?$/.test(value);
},
integer: function(value){
return /^-?\d+$/.test(value);
},
decimal: function(value){
return /^-?\d+\.\d+$/.test(value);
}
};
// 检查给定的值是否是纯对象,纯对象是指通过 {} 或 new Object() 声明的对象
export const isPlainObject = function(value) {
if (!value || objToString.call(value) !== "[object Object]") {
return false;
}
var prototype = getPrototypeOf(value);
if (prototype === null) {
return true;
}
var constructor = hasOwnProperty.call(prototype, "constructor") && prototype.constructor;
return typeof constructor === "function" && funToString.call(constructor) === funToString.call(Object);
};
// 检查给定的值是否是数组
export const isArray = function(value) {
return objToString.call(value) === "[object Array]";
};
export const deleteArray = function (arr,value) {
let index = arr.indexOf( value )
arr.splice(index,1)
return arr.join(',')
}
// 检查给定的值是否是字符串
export const isString = function(value) {
return objToString.call(value) === "[object String]";
};
let utils = {};
// 日期操作
utils.date = {
parse: function(){
var args = arguments, date = null;
if(args.length == 0){
date = new Date();
}
else if(args.length == 1){
if(isString(args[0])){
date = new Date(args[0].replace(/-/g, "/"));
}
else if(isNumber(args[0])){
date = new Date(args[0]);
}
}
else if(args.length == 3){
date = new Date(args[0], args[1], args[2]);
}
return date;
},
timestamp: function(date){
date = this.parse(date);
return date.getTime();
},
format: function(date, format){
date = this.parse(date);
var model = {
"M+": date.getMonth()+1,
"d+": date.getDate(),
"h+": date.getHours() == 12 ? 12 : date.getHours() % 12,
"H+": date.getHours(),
"m+": date.getMinutes(),
"s+": date.getSeconds(),
"S": date.getMilliseconds(),
"q+": Math.floor((date.getMonth() + 3) / 3)
};
var week = {
"0": "/u65e5",
"1": "/u4e00",
"2": "/u4e8c",
"3": "/u4e09",
"4": "/u56db",
"5": "/u4e94",
"6": "/u516d"
};
if(/(y+)/.test(format)){
format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
}
if(/(E+)/.test(format)){
format = format.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "/u661f/u671f" : "/u5468") : "") + week[date.getDay() + ""]);
}
for(var key in model){
if(new RegExp("(" + key + ")").test(format)){
format = format.replace(RegExp.$1, (RegExp.$1.length == 1) ? (model[key]) : (("00" + model[key]).substr(("" + model[key]).length)));
}
}
return format;
},
plus: function(date, value){
date = this.parse(date);
date = date.getTime();
date = date + parseInt(value) * 24 * 60 * 60 * 1000;
return date;
},
minus: function(date, value){
date = this.parse(date);
date = date.getTime();
date = date - parseInt(value) * 24 * 60 * 60 * 1000;
return date;
}
};
export {utils}