refactor(popover): refactor popover manager for better logic

This commit is contained in:
07akioni 2019-12-26 16:08:19 +08:00
parent 6ce780ae7b
commit 76b54cda3d
8 changed files with 36 additions and 74 deletions

View File

@ -1,6 +1,6 @@
{
"name": "naive-ui",
"version": "0.6.5",
"version": "0.6.6",
"description": "",
"main": "index.js",
"scripts": {

View File

@ -34,7 +34,7 @@ export default {
props: {
...context.props,
controller,
detachedContainerClass: 'n-popconfirm'
containerClass: 'n-popconfirm'
},
scopedSlots: {
activator: () => slots.activator && slots.activator(),

View File

@ -62,9 +62,9 @@ export default {
type: Boolean,
default: false
},
detachedContainerClass: {
containerClass: {
type: String,
default: 'n-popover-detached-content-container'
default: undefined
},
detached: {
type: Boolean,
@ -82,16 +82,19 @@ export default {
},
data () {
return {
memorizedId: null,
internalActive: false,
show: false
}
},
created () {
this.memorizedId = this.id
popoverManager.registerContent(this.memorizedId, this)
if (this.active) this.show = true
},
watch: {
active (newActive) {
if (newActive) {
active (value) {
if (value) {
this.$parent.transferElement()
this.$emit('show')
} else {
@ -128,7 +131,6 @@ export default {
}
},
mounted () {
popoverManager.registerContent(this)
if (this.active) {
this.$parent.transferElement()
// this.$nextTick().then(() => {
@ -143,13 +145,12 @@ export default {
},
updated () {
popoverManager.registerContent(this)
if (this.controller) {
this.controller.updatePosition = this.updatePosition
}
},
beforeDestroy () {
popoverManager.unregisterContent(this)
popoverManager.unregisterContent(this.memorizedId)
},
methods: {
cancelVanishTimer () {
@ -174,7 +175,7 @@ export default {
this.internalActive = false
},
activator () {
return popoverManager.getActivatorInstance(this)
return popoverManager.getActivatorInstance(this.memorizedId)
},
handleMouseEnter () {
this.cancelVanishTimer()
@ -236,7 +237,7 @@ export default {
return h('div', {
staticClass: 'n-detached-content-container',
class: {
[this.detachedContainerClass]: true,
[this.containerClass]: true,
[this.namespace]: this.namespace
},
ref: 'contentContainer'

View File

@ -1,64 +1,25 @@
function abstractRegister (self, componentInstance, mapKey, reverseMapKey) {
if (componentInstance && componentInstance.id) {
const map = self[mapKey]
const reverseMap = self[reverseMapKey]
const id = componentInstance.id
const memorizedId = reverseMap.get(componentInstance)
if (map.has(id)) {
map.delete(id)
}
if (map.has(memorizedId)) {
map.delete(memorizedId)
}
map.set(id, componentInstance)
reverseMap.set(componentInstance, id)
}
}
function abstractUnregister (self, componentInstance, mapKey, reverseMapKey) {
if (componentInstance && componentInstance.id) {
const map = self[mapKey]
const reverseMap = self[reverseMapKey]
const id = componentInstance.id
const memorizedId = reverseMap.get(componentInstance)
if (map.has(id)) {
map.delete(id)
}
if (map.has(memorizedId)) {
map.delete(memorizedId)
}
map.delete(componentInstance)
}
}
class PopoverManager {
constructor () {
this.id2activator = new Map()
this.activator2id = new Map()
this.id2content = new Map()
this.content2id = new Map()
this.id2Content = new Map()
this.id2Activator = new Map()
}
registerActivator (activator) {
// console.log(`[PopoverManager.registerActivator]`)
abstractRegister(this, activator, 'id2activator', 'activator2id')
registerActivator (key, instance) {
this.id2Activator.set(key, instance)
}
registerContent (content) {
// console.log(`[PopoverManager.registerContent]`)
abstractRegister(this, content, 'id2content', 'content2id')
registerContent (key, instance) {
this.id2Content.set(key, instance)
}
unregisterActivator (activator) {
// console.log(`[PopoverManager.unregisterActivator]`)
abstractUnregister(this, activator, 'id2activator', 'activator2id')
unregisterActivator (key) {
this.id2Activator.delete(key)
}
unregisterContent (content) {
// console.log(`[PopoverManager.unregisterContent]`)
abstractUnregister(this, content, 'id2content', 'content2id')
unregisterContent (key) {
this.id2Content.delete(key)
}
getContentInstance (activator) {
return this.id2content.get(activator.id) || null
getContentInstance (key) {
return this.id2Content.get(key) || null
}
getActivatorInstance (content) {
return this.id2activator.get(content.id) || null
getActivatorInstance (key) {
return this.id2Activator.get(key) || null
}
}

View File

@ -35,6 +35,10 @@ export default {
default: null
}
},
created () {
this.memorizedId = this.id
popoverManager.registerActivator(this.memorizedId, this)
},
computed: {
triggeredByClick () {
return this.trigger === 'click'
@ -52,6 +56,7 @@ export default {
},
data () {
return {
memorizedId: null,
internalActive: false,
delayTimerId: null,
vanishTimerId: null
@ -60,7 +65,6 @@ export default {
mounted () {
// console.log('[Activator.mounted] id', this.id)
// console.log('[Activator.mounted] active', this.active)
popoverManager.registerActivator(this)
this.registerListeners()
if (this.controller) {
this.controller.show = this.activate
@ -69,8 +73,6 @@ export default {
},
beforeUpdate () {},
updated () {
// console.log('Activator Updated', this.id)
popoverManager.registerActivator(this)
this.registerListeners()
if (this.controller) {
this.controller.show = this.activate
@ -78,8 +80,7 @@ export default {
}
},
beforeDestroy () {
// console.log('Activator Destroyed', this.id)
popoverManager.unregisterActivator(this)
popoverManager.unregisterActivator(this.memorizedId)
if (this.controller) {
this.controller.show = null
this.controller.hide = null
@ -101,8 +102,7 @@ export default {
this.internalActive = false
},
content () {
// console.log(popoverManager, this)
return popoverManager.getContentInstance(this)
return popoverManager.getContentInstance(this.memorizedId)
},
handleClick () {
if (this.triggeredByClick) {

View File

@ -65,7 +65,7 @@ export default {
type: Object,
default: null
},
detachedContainerClass: {
containerClass: {
type: String,
default: 'n-popover'
},

View File

@ -56,7 +56,7 @@ export default {
return h(NPopover, {
props: {
trigger: 'click',
detachedContainerClass: 'n-popselect',
containerClass: 'n-popselect',
controller
},
on: {

View File

@ -67,7 +67,7 @@ export default {
on: context.listeners,
props: {
...context.props,
detachedContainerClass: 'n-tooltip',
containerClass: 'n-tooltip',
contentClass: 'n-tooltip-content'
},
scopedSlots: {