magiccube-vue3
Version:
vue3-js版组件库
157 lines (144 loc) • 5.74 kB
JavaScript
import { inject, watch, nextTick, computed } from 'vue'
/**
* 列表表身 列元素控件
*/
const Cell = {
props: {
rowIndex: Number,
width: Number,
align: String,
keyName: String,
data: Array,
fixed: Boolean,
left: Number,
right: Number,
node: [Object, null],
fixedLeftLast: Boolean,
fixedRightFirst: Boolean,
},
setup(props) {
/* 鼠标是否悬停在本列中 */
const isHoverRow = inject('isHoverRow')
const showLeftShadow = inject('showLeftShadow')
const showRightShadow = inject('showRightShadow')
/* 通知其它列 鼠标悬停在本行 */
const handleHover = () => isHoverRow.value = props.rowIndex
/**
* 查看列中的内容是否超出列宽并进行了省略处理
* 如果满足条件 就给该列的inner绑定v-tooltip属性 进行鼠标移入弹出提示
*/
const _data = props.data[props.rowIndex]
const content = _data[props.keyName]
const tipContent = content
return () => (
<td class={[
'mc-table__td',
{
'mc-table__td--fixed': props.fixed,
'mc-table--fixed-left-last': props.fixedLeftLast,
'mc-table--fixed-right-last': props.fixedRightFirst,
'mc-table--cell-shadow-left': props.fixedLeftLast && showLeftShadow.value,
'mc-table--cell-shadow-right': props.fixedRightFirst && showRightShadow.value,
}
]}
onMouseenter={handleHover}
style={{
left: props.left? props.left + 'px' : 0,
right: props.right? props.right + 'px' : 0,
width: props.width ? props.width + 'px' : '',
textAlign: props.align,
}}>
<div class="mc-table__td--inner"
v-ellipsis={tipContent}>
{ props.node }
</div>
</td>
)
}
}
export default {
props: {
column: Array,
data: Array,
width: String,
checkbox: Boolean,
fixedLeft: Number,
type: String,
checkboxWidth: [String, Number],
},
emits: ['render-done'],
setup(props, { emit }) {
const isHoverRow = inject('isHoverRow')
const handleSelectChange = inject('handleSelectChange')
const checkboxStyle = inject('checkboxStyle')
const showLeftShadow = inject('showLeftShadow')
/* 鼠标移出行时 改变鼠标悬停值 */
const handleRemoveHover = () => isHoverRow.value = -1
/* 过滤不可用列 */
const columns = computed(() => props.column.filter(n => n.enableCell))
/* 表身元素 */
const trNode = (item, index) => {
return (
<tr class={{
'hover-row': isHoverRow.value === index,
'disabled-row': item.isDisabledRow
}}
onMouseleave={handleRemoveHover}
style={{
height: props.type === 'fixed' && props.trHeightArray?.length ? props.trHeightArray[index] + 'px' : ''
}}>
{
props.checkbox ? (
<td class={[
'mc-table__td',
'mc-table-column__checkbox',
{
'mc-table--fixed-left-last': props.fixedLeft === 0 && props.type === 'fixed',
'mc-table--cell-shadow-left': props.fixedLeft === 0 && props.type === 'fixed' && showLeftShadow.value,
}
]}
style={{
width: props.checkboxWidth + 'px',
}}>
<McCheckbox v-model={item.isChecked} onChange={() => handleSelectChange(item)} style={checkboxStyle} />
</td>
) : ''
}
{
columns.value.map((n, i) => {
const { align, keyName } = n.props
return <Cell row-index={index}
width={n.cellWidth}
align={align}
keyName={keyName}
data={props.data}
fixed={n.fixedLeft || n.fixedRight}
left={n.fixedLeftPosition}
right={n.fixedRightPosition}
fixedLeftLast={n.fixedLeftLast}
fixedRightFirst={n.fixedRightFirst}
node={n} />
})
}
</tr>
)
}
// 渲染完成后设置滚动条属性
nextTick(() => emit('render-done'))
watch(() => props.data, () => nextTick(() => emit('render-done')))
watch(() => props.column, arr => nextTick(() => emit('render-done')))
return () => (
<table
border="0"
cellpadding="0"
cellspacing="0"
style={{
width: props.width,
tableLayout: 'fixed',
borderCollapse: 'separate'
}}>
<tbody>{ props.data.map(trNode) }</tbody>
</table>
)
}
}