| // reference https://github.com/noeldelgado/gemini-scrollbar/blob/master/index.js | 
|   | 
| import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event'; | 
| import scrollbarWidth from 'element-ui/src/utils/scrollbar-width'; | 
| import { toObject } from 'element-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.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); | 
|   } | 
| }; |