index.jsx 3.0 KB

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