blob: 2f1a0e5ef3fa81c8f3712e398b8bae6e93fc2f98 [file] [log] [blame]
import Vue from 'vue'
import { ItemProps, SlotProps } from './props'
const Wrapper = {
created() {
this.shapeKey = this.horizontal ? 'offsetWidth' : 'offsetHeight'
},
mounted() {
if (typeof ResizeObserver !== 'undefined') {
this.resizeObserver = new ResizeObserver(() => {
this.dispatchSizeChange()
})
this.resizeObserver.observe(this.$el)
}
},
// since component will be reused, so dispatch when updated
updated() {
this.dispatchSizeChange()
},
beforeDestroy() {
if (this.resizeObserver) {
this.resizeObserver.disconnect()
this.resizeObserver = null
}
},
methods: {
getCurrentSize() {
return this.$el ? this.$el[this.shapeKey] : 0
},
// tell parent current size identify by unique key
dispatchSizeChange() {
this.$parent.$emit(this.event, this.uniqueKey, this.getCurrentSize(), this.hasInitial)
}
}
}
// wrapping for item
export const Item = Vue.component('virtual-list-item', {
mixins: [Wrapper],
props: ItemProps,
render(h) {
const { tag, component, extraProps = {}, index, scopedSlots = {}, uniqueKey } = this
extraProps.source = this.source
extraProps.index = index
return h(tag, {
key: uniqueKey,
attrs: {
role: 'item'
}
}, [h(component, {
props: extraProps,
scopedSlots: scopedSlots
})])
}
})
// wrapping for slot
export const Slot = Vue.component('virtual-list-slot', {
mixins: [Wrapper],
props: SlotProps,
render(h) {
const { tag, uniqueKey } = this
return h(tag, {
key: uniqueKey,
attrs: {
role: uniqueKey
}
}, this.$slots.default)
}
})