UNPKG

element-nice-ui

Version:

A Component Library for Vue.js.

139 lines (122 loc) 3.29 kB
// reference https://github.com/noeldelgado/gemini-scrollbar/blob/master/index.js import { addResizeListener, removeResizeListener } from 'element-nice-ui/src/utils/resize-event' import scrollbarWidth from 'element-nice-ui/src/utils/scrollbar-width' import { toObject } from 'element-nice-ui/src/utils/util' import Bar from './bar' /* istanbul ignore next */ export default { name: 'ElScrollbar', components: { Bar }, props: { native: Boolean, wrapStyle: {}, wrapClass: {}, viewClass: {}, viewStyle: {}, noresize: Boolean, // 如果 container 尺寸不会发生变化,最好设置它可以优化性能 tag: { type: String, default: 'div' } }, data() { return { sizeWidth: '0', sizeHeight: '0', moveX: 0, moveY: 0 } }, computed: { wrap() { return this.$refs.wrap } }, render(h) { let gutter = scrollbarWidth() let style = this.wrapStyle if (gutter) { const gutterWith = `-${gutter}px` const gutterStyle = `margin-bottom: ${gutterWith}; margin-right: ${gutterWith};` if (Array.isArray(this.wrapStyle)) { style = toObject(this.wrapStyle) style.marginRight = style.marginBottom = gutterWith } else if (typeof this.wrapStyle === 'string') { style += gutterStyle } else { style = gutterStyle } } const view = h( this.tag, { class: ['el-scrollbar__view', this.viewClass], style: this.viewStyle, ref: 'resize' }, this.$slots.default ) const wrap = ( <div ref='wrap' style={style} onScroll={this.handleScroll} class={[ this.wrapClass, 'el-scrollbar__wrap', gutter ? '' : 'el-scrollbar__wrap--hidden-default' ]} > {[view]} </div> ) let nodes if (!this.native) { nodes = [ wrap, <Bar move={this.moveX} size={this.sizeWidth}></Bar>, <Bar vertical move={this.moveY} size={this.sizeHeight}></Bar> ] } else { nodes = [ <div ref='wrap' class={[this.wrapClass, 'el-scrollbar__wrap']} style={style} > {[view]} </div> ] } return h('div', { class: 'el-scrollbar' }, nodes) }, methods: { handleScroll() { const wrap = this.wrap this.$emit('scroll', wrap.scrollTop) this.moveY = (wrap.scrollTop * 100) / wrap.clientHeight this.moveX = (wrap.scrollLeft * 100) / wrap.clientWidth }, update() { let heightPercentage, widthPercentage const wrap = this.wrap if (!wrap) return heightPercentage = (wrap.clientHeight * 100) / wrap.scrollHeight widthPercentage = (wrap.clientWidth * 100) / wrap.scrollWidth this.sizeHeight = heightPercentage < 100 ? heightPercentage + '%' : '' this.sizeWidth = widthPercentage < 100 ? widthPercentage + '%' : '' } }, mounted() { if (this.native) return this.$nextTick(this.update) !this.noresize && addResizeListener(this.$refs.resize, this.update) }, beforeDestroy() { if (this.native) return !this.noresize && removeResizeListener(this.$refs.resize, this.update) } }