refactor(dropdown): use v-binder

This commit is contained in:
07akioni 2020-11-26 17:20:54 +08:00
parent 68b6363632
commit bad4208012
6 changed files with 57 additions and 56 deletions

View File

@ -93,6 +93,6 @@
"vfonts": "^0.0.1", "vfonts": "^0.0.1",
"vooks": "^0.0.1", "vooks": "^0.0.1",
"vue": "^3.0.2", "vue": "^3.0.2",
"vueuc": "^0.1.0-alpha.15" "vueuc": "^0.1.0-alpha.17"
} }
} }

View File

@ -19,7 +19,6 @@ const zindexable = {
el[ctx].enabled = enabled el[ctx].enabled = enabled
}, },
unmounted (el) { unmounted (el) {
// TODO: bug, sometimes vue will unmount popover twice when change route
if (el[ctx].unmounted) return if (el[ctx].unmounted) return
el[ctx].unmounted = true el[ctx].unmounted = true
zIndexManager.unregisterElement(el) zIndexManager.unregisterElement(el)

View File

@ -1,6 +1,10 @@
import { h, computed, inject, ref, Transition } from 'vue' import { h, computed, inject, ref, Transition } from 'vue'
import {
VBinder,
VTarget,
VFollower
} from 'vueuc'
import { render } from '../../_utils/vue' import { render } from '../../_utils/vue'
import { placeable } from '../../_mixins'
import { ChevronRightIcon } from '../../_base/icons' import { ChevronRightIcon } from '../../_base/icons'
import NIcon from '../../icon' import NIcon from '../../icon'
import { useMemo } from 'vooks' import { useMemo } from 'vooks'
@ -10,9 +14,6 @@ import { isSubmenuNode } from './utils'
export default { export default {
name: 'DropdownOption', name: 'DropdownOption',
mixins: [
placeable
],
provide () { provide () {
return { return {
NDropdownOption: this NDropdownOption: this
@ -32,7 +33,7 @@ export default {
default: null default: null
}, },
placement: { placement: {
...placeable.props.placement, type: String,
default: 'right-start' default: 'right-start'
} }
}, },
@ -83,31 +84,10 @@ export default {
const { key } = props.tmNode const { key } = props.tmNode
return activeKeyPath.includes(key) || activeKeyPath.includes(key) return activeKeyPath.includes(key) || activeKeyPath.includes(key)
}), }),
// placeable
trackingRef: ref(null),
offsetContainerRef: ref(null),
bodyRef: ref(null),
NDropdownOption NDropdownOption
} }
}, },
computed: {
__placeableEnabled () {
return this.mergedShowSubmenu
}
},
methods: { methods: {
__placeableTracking () {
return this.trackingRef
},
__placeableTracked () {
return this.offsetContainerRef
},
__placeableOffsetContainer () {
return this.offsetContainerRef
},
__placeableBody () {
return this.bodyRef
},
handleSubmenuBeforeEnter () { handleSubmenuBeforeEnter () {
this.enteringSubmenu = true this.enteringSubmenu = true
}, },
@ -171,7 +151,6 @@ export default {
} = this } = this
const submenuVNode = mergedShowSubmenu const submenuVNode = mergedShowSubmenu
? h(NDropdownMenu, { ? h(NDropdownMenu, {
ref: 'bodyRef',
tmNodes: this.tmNode.children, tmNodes: this.tmNode.children,
parentKey: this.tmNode.key parentKey: this.tmNode.key
}) })
@ -222,27 +201,43 @@ export default {
}) : null }) : null
]) ])
]), ]),
this.hasSubmenu ? h('div', { this.hasSubmenu ? h(VBinder, null, {
ref: 'offsetContainerRef', default: () => {
class: 'n-dropdown-offset-container' return h(VTarget, null, {
}, [ default: () => {
h( return h('div', {
'div', class: 'n-dropdown-offset-container'
{ }, [
ref: 'trackingRef', h(VFollower, {
class: 'n-dropdown-menu-wrapper' show: this.mergedShowSubmenu,
}, teleportDisabled: true,
[ placement: this.placement
animated ? h(Transition, { }, {
onBeforeEnter: this.handleSubmenuBeforeEnter, default: () => {
onAfterEnter: this.handleSubmenuAfterEnter, return h(
name: 'n-fade-in-scale-up-transition' 'div',
}, { {
default: () => submenuVNode class: 'n-dropdown-menu-wrapper'
}) : submenuVNode },
] [
) animated ? h(Transition, {
]) : null onBeforeEnter: this.handleSubmenuBeforeEnter,
onAfterEnter: this.handleSubmenuAfterEnter,
name: 'n-fade-in-scale-up-transition',
appear: true
}, {
default: () => submenuVNode
}) : submenuVNode
]
)
}
})
])
}
})
}
})
: null
]) ])
} }
} }

View File

@ -55,7 +55,8 @@ export default c([
}), }),
cE('suffix', { cE('suffix', {
boxSizing: 'border-box', boxSizing: 'border-box',
flex: 1, flexGrow: 0,
flexShrink: 0,
display: 'flex', display: 'flex',
justifyContent: 'flex-end', justifyContent: 'flex-end',
alignItems: 'center', alignItems: 'center',
@ -100,6 +101,7 @@ export default c([
pointerEvents: 'all' pointerEvents: 'all'
}), }),
cB('dropdown-menu-wrapper', { cB('dropdown-menu-wrapper', {
transformOrigin: 'inherit',
width: 'fit-content' width: 'fit-content'
}) })
]) ])

View File

@ -198,7 +198,7 @@ export default {
'n-popover--no-arrow': !this.showArrow, 'n-popover--no-arrow': !this.showArrow,
'n-popover--shadow': this.shadow, 'n-popover--shadow': this.shadow,
[this.bodyClass]: this.bodyClass, [this.bodyClass]: this.bodyClass,
'n-popover--styled': !this.raw 'n-popover--raw': this.raw
} }
], ],
ref: 'body', ref: 'body',

View File

@ -1,4 +1,4 @@
import { c, cTB, cB, cM } from '../../../_utils/cssr' import { c, cTB, cB, cM, cNotM } from '../../../_utils/cssr'
import { depx, pxfy } from '../../../_utils/css' import { depx, pxfy } from '../../../_utils/css'
export default c([ export default c([
@ -27,9 +27,7 @@ export default c([
position: relative; position: relative;
font-size: 13px; font-size: 13px;
color: ${textColor}; color: ${textColor};
background-color: ${color};
border-radius: ${borderRadius};
padding: 8px 14px;
` `
}, [ }, [
bodyTransition( bodyTransition(
@ -37,6 +35,13 @@ export default c([
cubicBezierEaseOut, cubicBezierEaseOut,
cubicBezierEaseIn cubicBezierEaseIn
), ),
cNotM('raw', {
raw: `
background-color: ${color};
border-radius: ${borderRadius};
padding: 8px 14px;
`
}),
cB('popover-arrow-wrapper', { cB('popover-arrow-wrapper', {
raw: ` raw: `
position: absolute; position: absolute;