index.jsx 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { ref, onMounted, watch, nextTick } from 'vue'
  2. import { ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus'
  3. import CipTableButton from '@cip/components/cip-table-button'
  4. import { useTable } from '../hooks/use-table'
  5. const getButtonInfo = (vnode) => {
  6. if (vnode.component) {
  7. const text = vnode.component.slots.default()
  8. return {
  9. ...vnode.component.ctx._.props,
  10. ...vnode.component.ctx._.attrs,
  11. text
  12. }
  13. }
  14. return {}
  15. }
  16. const RenderComponent = (props) => {
  17. const list = props.buttonList // .value
  18. let dropDownNode
  19. let buttonNodeList = list
  20. if (list.length > props.limit) {
  21. buttonNodeList = list.slice(0, props.limit - 1)
  22. dropDownNode = <ElDropdown style={'margin-left: 8px'} size={props.size}>
  23. {{
  24. default: () => <CipTableButton>更多<i class={'el-icon-caret-bottom'}/></CipTableButton>,
  25. dropdown: () => <ElDropdownMenu>
  26. {
  27. list.slice(props.limit - 1).map(item => {
  28. const { onClick, text, disabled } = getButtonInfo(item)
  29. return <ElDropdownItem onClick={onClick} disabled={disabled}>{text}</ElDropdownItem>
  30. })
  31. }
  32. </ElDropdownMenu>
  33. }}
  34. </ElDropdown>
  35. }
  36. const result = buttonNodeList.map(item => {
  37. const { onClick, text, type, icon, disabled } = getButtonInfo(item)
  38. return <CipTableButton type={type} disabled={disabled} icon={icon} onClick={onClick}>{text}</CipTableButton>
  39. })
  40. if (dropDownNode) {
  41. result.push(dropDownNode)
  42. }
  43. return result
  44. }
  45. export default {
  46. name: 'CipTableHandler',
  47. props: {
  48. limit: { type: Number, default: 3 },
  49. row: { type: Object, required: true }
  50. },
  51. setup (props, { slots }) {
  52. const cipTable = useTable()
  53. const buttonList = ref([])
  54. const originRef = ref()
  55. let vnodeList = []
  56. onMounted(() => {
  57. watch(() => props.row, (val) => {
  58. nextTick().then(() => collectButtons())
  59. }, { immediate: true, deep: true })
  60. })
  61. const collectButtons = () => {
  62. buttonList.value = []
  63. vnodeList.forEach(vnode => getButtons(vnode))
  64. }
  65. const getButtons = (vnode) => {
  66. if (vnode.shapeFlag === 16) {
  67. vnode.children.forEach(v => getButtons(v))
  68. }
  69. if (vnode.shapeFlag === 36) {
  70. const componentName = (vnode.type.name || '').toLowerCase()
  71. if (componentName.indexOf('button') > -1) {
  72. buttonList.value.push(vnode)
  73. } else {
  74. if (vnode.component) {
  75. const children = vnode.component.subTree.children || []
  76. children.forEach(v => getButtons(v))
  77. }
  78. }
  79. }
  80. }
  81. return () => {
  82. vnodeList = slots.default?.()
  83. return <div class={'cip-table-handler'}>
  84. <div ref={el => { originRef.value = el }} style={'display: none'}>{vnodeList}</div>
  85. <RenderComponent limit={props.limit} size={cipTable.size} buttonList={buttonList.value} />
  86. </div>
  87. }
  88. }
  89. }