123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- import { ref, onMounted, watch, nextTick, computed } from 'vue'
- import { ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus'
- import CipButtonText from '@cip/components/cip-button-text'
- import CipButton from '@cip/components/cip-button'
- import { useTable } from '../hooks/use-table'
- import './index.less'
- import { getUsingConfig } from '@cip/utils/util'
- const getButtonInfo = (vnode) => {
- if (vnode.component) {
- const text = vnode.component.slots.default()
- // console.log(vnode.component.emitsOptions.click)
- const info = { ...vnode.component.ctx._.props, ...vnode.component.ctx._.attrs }
- const { onClick = (e) => vnode.component.ctx._.emit('click', e) } = info
- return {
- ...info,
- onClick,
- text
- }
- }
- return {}
- }
- const RenderComponent = (props) => {
- const list = props.buttonList // .value
- let dropDownNode
- let buttonNodeList = list
- if (list.length > props.limit) {
- buttonNodeList = list.slice(0, props.limit - 1)
- dropDownNode = <ElDropdown style={'margin-left: 8px'} size={props.size}>
- {{
- default: () => props.buttonComp === 'button'
- ? <CipButton square={true} icon={'el-icon-arrow-down'}/>
- : <CipButtonText>更多<i class={'el-icon-caret-bottom'}/></CipButtonText>,
- dropdown: () => <ElDropdownMenu>
- {
- list.slice(props.limit - 1).map(item => {
- const { onClick, text, disabled } = getButtonInfo(item)
- return <ElDropdownItem onClick={onClick} disabled={disabled}>{text}</ElDropdownItem>
- })
- }
- </ElDropdownMenu>
- }}
- </ElDropdown>
- }
- const result = buttonNodeList.map(item => {
- const { onClick, text, type, icon, disabled } = getButtonInfo(item)
- const ButtonComponent = props.buttonComp === 'button' ? CipButton : CipButtonText
- return <ButtonComponent type={type} disabled={disabled} icon={icon} onClick={onClick}>{text}</ButtonComponent>
- })
- if (dropDownNode) {
- result.push(dropDownNode)
- }
- return result
- }
- export default {
- name: 'CipTableHandler',
- props: {
- limit: { type: Number },
- row: { type: Object, required: true },
- buttonComp: { type: String, default: 'text', validate: (val) => ['text', 'button'].includes(val) }
- },
- setup (props, { slots }) {
- const cipTable = useTable()
- const buttonList = ref([])
- const originRef = ref()
- const handlerLimit = computed(() => {
- return getUsingConfig(props.limit, props.buttonComp === 'text' ? 3 : 4)
- })
- let vnodeList = []
- onMounted(() => {
- watch(() => props.row, () => {
- nextTick().then(() => collectButtons())
- }, { immediate: true, deep: true })
- })
- const collectButtons = () => {
- buttonList.value = []
- vnodeList.forEach(vnode => getButtons(vnode))
- }
- const getButtons = (vnode) => {
- if (vnode.shapeFlag === 16) { // 数组
- vnode.children.forEach(v => getButtons(v))
- }
- if (vnode.shapeFlag === 17) { // 原生的dom
- vnode.children.forEach(v => getButtons(v))
- }
- if (vnode.shapeFlag === 36) { // 组件
- const componentName = (vnode.type.name || '').toLowerCase()
- if (componentName.indexOf('button') > -1) {
- buttonList.value.push(vnode)
- } else {
- if (vnode.component) {
- const children = vnode.component.subTree.children || []
- children.forEach(v => getButtons(v))
- }
- }
- }
- }
- return () => {
- vnodeList = slots.default?.()
- return <div class={'cip-table-handler'}>
- <div ref={el => { originRef.value = el }} style={'display: none'}>{vnodeList}</div>
- <RenderComponent limit={handlerLimit.value} size={cipTable.size} buttonList={buttonList.value} buttonComp={props.buttonComp} />
- </div>
- }
- }
- }
|