init
This commit is contained in:
138
uni_modules/nutui-uni/components/table/index.scss
Normal file
138
uni_modules/nutui-uni/components/table/index.scss
Normal file
@@ -0,0 +1,138 @@
|
||||
/* stylelint-disable no-duplicate-selectors */
|
||||
|
||||
.nut-theme-dark {
|
||||
.nut-table {
|
||||
&__main {
|
||||
color: $dark-color;
|
||||
background-color: $dark-background2;
|
||||
|
||||
&--striped {
|
||||
.nut-table__main__head {
|
||||
&__tr {
|
||||
background-color: $dark-background3;
|
||||
}
|
||||
}
|
||||
|
||||
.nut-table__main__body {
|
||||
&__tr:nth-child(odd) {
|
||||
background-color: $dark-color-gray;
|
||||
}
|
||||
}
|
||||
|
||||
.nut-table__main__body {
|
||||
&__tr:nth-child(even) {
|
||||
background-color: $dark-background3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__summary {
|
||||
color: $dark-color;
|
||||
background-color: $dark-background;
|
||||
}
|
||||
|
||||
&__nodata {
|
||||
color: $dark-color;
|
||||
background-color: $dark-background;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nut-table {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
font-size: $font-size-2;
|
||||
|
||||
&__main {
|
||||
display: table;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
border-collapse: collapse;
|
||||
|
||||
&--striped {
|
||||
.nut-table__main__head {
|
||||
&__tr {
|
||||
background-color: $table-tr-even-bg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.nut-table__main__body {
|
||||
&__tr:nth-child(odd) {
|
||||
background-color: $table-tr-odd-bg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.nut-table__main__body {
|
||||
&__tr:nth-child(even) {
|
||||
background-color: $table-tr-even-bg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__head,
|
||||
&__body {
|
||||
&__tr {
|
||||
display: table-row;
|
||||
|
||||
&__th {
|
||||
display: table-cell;
|
||||
padding: $table-cols-padding;
|
||||
}
|
||||
|
||||
&__td {
|
||||
display: table-cell;
|
||||
padding: $table-cols-padding;
|
||||
|
||||
&__nodata {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
&--border {
|
||||
border: 1px solid $table-border-color;
|
||||
}
|
||||
|
||||
&--alignleft,
|
||||
&--align {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&--aligncenter {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&--alignright {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__head {
|
||||
display: table-header-group;
|
||||
}
|
||||
|
||||
&__body {
|
||||
display: table-row-group;
|
||||
}
|
||||
}
|
||||
|
||||
&__summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
padding: $table-cols-padding;
|
||||
}
|
||||
|
||||
&__nodata {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 30px;
|
||||
padding: $table-cols-padding;
|
||||
}
|
||||
}
|
||||
2
uni_modules/nutui-uni/components/table/index.ts
Normal file
2
uni_modules/nutui-uni/components/table/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './table'
|
||||
export * from './types'
|
||||
12
uni_modules/nutui-uni/components/table/renderColumn.ts
Normal file
12
uni_modules/nutui-uni/components/table/renderColumn.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { PropType } from 'vue'
|
||||
import { defineComponent, h } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
slots: Array as PropType<Array<() => void | undefined>>,
|
||||
record: Object,
|
||||
},
|
||||
setup(props: any) {
|
||||
return () => h('view', {}, props.slots[0] ? props.slots[0](props.record) : props.slots[1](props.record))
|
||||
},
|
||||
})
|
||||
38
uni_modules/nutui-uni/components/table/table.ts
Normal file
38
uni_modules/nutui-uni/components/table/table.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
import { commonProps, makeArrayProp, truthProp } from '../_utils'
|
||||
import type { TableColumnProps } from './types'
|
||||
|
||||
export const tableProps = {
|
||||
...commonProps,
|
||||
/**
|
||||
* @description 是否显示边框
|
||||
*/
|
||||
bordered: truthProp,
|
||||
/**
|
||||
* @description 表头数据
|
||||
*/
|
||||
columns: makeArrayProp<TableColumnProps>([]),
|
||||
/**
|
||||
* @description 表格数据
|
||||
*/
|
||||
data: makeArrayProp<any>([]),
|
||||
/**
|
||||
* @description 是否显示简介
|
||||
*/
|
||||
summary: {
|
||||
type: Function,
|
||||
default: null,
|
||||
},
|
||||
/**
|
||||
* @description 条纹是否明暗交替
|
||||
*/
|
||||
striped: Boolean,
|
||||
}
|
||||
|
||||
export type TableProps = ExtractPropTypes<typeof tableProps>
|
||||
|
||||
export const tableEmits = {
|
||||
sorter: (val: TableColumnProps) => val instanceof Object,
|
||||
}
|
||||
|
||||
export type TableEmits = typeof tableEmits
|
||||
145
uni_modules/nutui-uni/components/table/table.vue
Normal file
145
uni_modules/nutui-uni/components/table/table.vue
Normal file
@@ -0,0 +1,145 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, defineComponent, reactive, watch } from 'vue'
|
||||
import { PREFIX } from '../_constants'
|
||||
import { getMainClass } from '../_utils'
|
||||
import { useTranslate } from '../../locale'
|
||||
import NutIcon from '../icon/icon.vue'
|
||||
import RenderColumn from './renderColumn'
|
||||
import { tableEmits, tableProps } from './table'
|
||||
import type { TableColumnProps } from './types'
|
||||
|
||||
const props = defineProps(tableProps)
|
||||
const emit = defineEmits(tableEmits)
|
||||
const state = reactive({
|
||||
curData: props.data,
|
||||
})
|
||||
const classes = computed(() => {
|
||||
return getMainClass(props, componentName)
|
||||
})
|
||||
|
||||
function cellClasses(item: TableColumnProps) {
|
||||
return {
|
||||
'nut-table__main__head__tr--border': props.bordered,
|
||||
[`nut-table__main__head__tr--align${item.align ? item.align : ''}`]: true,
|
||||
}
|
||||
}
|
||||
|
||||
function _stylehead(item: TableColumnProps) {
|
||||
return item.stylehead ? item.stylehead : ''
|
||||
}
|
||||
function _stylecolumn(item: TableColumnProps) {
|
||||
return item.stylecolumn ? item.stylecolumn : ''
|
||||
}
|
||||
|
||||
function getColumnItem(value: string): TableColumnProps {
|
||||
return props.columns.filter((item: TableColumnProps) => item.key === value)[0]
|
||||
}
|
||||
function getColumnItemStyle(value: string) {
|
||||
const style = props.columns.filter((item: TableColumnProps) => item.key === value)
|
||||
return style[0].stylecolumn ? style[0].stylecolumn : ''
|
||||
}
|
||||
function handleSorterClick(item: TableColumnProps) {
|
||||
if (item.sorter) {
|
||||
emit('sorter', item)
|
||||
state.curData
|
||||
= typeof item.sorter === 'function'
|
||||
? state.curData.sort(item.sorter)
|
||||
: item.sorter === 'default'
|
||||
? state.curData.sort()
|
||||
: state.curData
|
||||
}
|
||||
}
|
||||
|
||||
function sortDataItem() {
|
||||
return props.columns.map((columns: TableColumnProps) => {
|
||||
return [columns.key, columns.render]
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
(val) => {
|
||||
state.curData = val.slice()
|
||||
},
|
||||
)
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
const componentName = `${PREFIX}-table`
|
||||
const { translate } = useTranslate(componentName)
|
||||
|
||||
export default defineComponent({
|
||||
name: componentName,
|
||||
options: {
|
||||
virtualHost: true,
|
||||
addGlobalClass: true,
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view :class="classes" :style="customStyle">
|
||||
<view class="nut-table__main" :class="{ 'nut-table__main--striped': striped }">
|
||||
<view class="nut-table__main__head">
|
||||
<view class="nut-table__main__head__tr">
|
||||
<view
|
||||
v-for="item in columns"
|
||||
:key="item.key"
|
||||
class="nut-table__main__head__tr__th"
|
||||
:class="cellClasses(item)"
|
||||
:style="item.stylehead"
|
||||
@click="handleSorterClick(item)"
|
||||
>
|
||||
{{ item.title }}
|
||||
<!-- <slot name="icon" > -->
|
||||
<NutIcon v-if="item.sorter" name="down-arrow" size="12px" />
|
||||
<!-- </slot> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="nut-table__main__body">
|
||||
<view v-for="item in state.curData" :key="item" class="nut-table__main__body__tr">
|
||||
<view
|
||||
v-for="[value, render] in sortDataItem()"
|
||||
:key="value as string"
|
||||
class="nut-table__main__body__tr__td"
|
||||
:class="cellClasses(getColumnItem(value as string))"
|
||||
:style="getColumnItemStyle(value as string)"
|
||||
>
|
||||
<!-- #ifdef H5 -->
|
||||
<RenderColumn
|
||||
v-if="typeof item[value as string] === 'function' || typeof render === 'function'"
|
||||
:slots="[render, item[value as string]]"
|
||||
:record="item"
|
||||
/>
|
||||
<view v-else>
|
||||
{{ item[value as string] }}
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef H5 -->
|
||||
<view>
|
||||
{{ item[value as string] }}
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="summary" class="nut-table__summary">
|
||||
<rich-text class="nut-table__summary__text" :nodes="summary().value" />
|
||||
</view>
|
||||
<view v-if="!state.curData.length" class="nut-table__nodata">
|
||||
<div class="nut-table__nodata" :class="{ 'nut-table__nodata--border': bordered }">
|
||||
<slot name="nodata" />
|
||||
<div v-if="!$slots.nodata" class="nut-table__nodata__text">
|
||||
{{ translate('noData') }}
|
||||
</div>
|
||||
</div>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import './index';
|
||||
</style>
|
||||
38
uni_modules/nutui-uni/components/table/types.ts
Normal file
38
uni_modules/nutui-uni/components/table/types.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import type { VNode, VNodeChild } from 'vue'
|
||||
|
||||
export interface TableColumnProps {
|
||||
/**
|
||||
* @description 列的唯一标识
|
||||
*/
|
||||
key?: string
|
||||
/**
|
||||
* @description 表头标题
|
||||
*/
|
||||
title?: string
|
||||
/**
|
||||
* @description 列的对齐方式,可选值`left`,`center`
|
||||
*/
|
||||
align?: 'left' | 'right'
|
||||
/**
|
||||
* @description 表头样式
|
||||
*/
|
||||
stylehead?: string
|
||||
/**
|
||||
* @description 表格列样式
|
||||
*/
|
||||
stylecolumn?: string
|
||||
/**
|
||||
* @description 排序,可选值有 `true`,`function`, `default`, 其中 `default`表示点击之后可能会依赖接口, `function`可以返回具体的排序函数, `default`表示采用默认的排序算法
|
||||
* @param row1
|
||||
* @param row2
|
||||
* @returns
|
||||
*/
|
||||
sorter?: (row1: any, row2: any) => number
|
||||
/**
|
||||
* @description 自定义渲染列数据,优先级高,仅支持`H5`
|
||||
* @param rowData
|
||||
* @param rowIndex
|
||||
* @returns
|
||||
*/
|
||||
render?: (rowData?: object, rowIndex?: number) => VNodeChild | string | VNode
|
||||
}
|
||||
Reference in New Issue
Block a user