UNPKG

ivue-material-plus

Version:

A high quality UI components Library with Vue.js

1 lines 10.9 kB
{"version":3,"file":"index2.mjs","sources":["../../../../../src/components/ivue-scrollbar/index.vue"],"sourcesContent":["<template>\r\n <div :class=\"prefixCls\" ref=\"scrollbar\">\r\n <div\r\n :class=\"wrapperClasses\"\r\n :style=\"wrapperStyles\"\r\n @scroll=\"handleScroll\"\r\n ref=\"scrollbarWrapper\"\r\n >\r\n <component\r\n :is=\"tag\"\r\n :class=\"contentClasses\"\r\n :style=\"contentStyle\"\r\n ref=\"resize\"\r\n >\r\n <slot></slot>\r\n </component>\r\n </div>\r\n <!-- 是否使用原生滚动条样式 -->\r\n <template v-if=\"!native\">\r\n <bar\r\n :barHeight=\"data.barHeight\"\r\n :barWidth=\"data.barWidth\"\r\n :always=\"always\"\r\n :ratioX=\"data.ratioX\"\r\n :ratioY=\"data.ratioY\"\r\n ref=\"bar\"\r\n ></bar>\r\n </template>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\">\r\nimport {\r\n computed,\r\n defineComponent,\r\n ref,\r\n reactive,\r\n onMounted,\r\n nextTick,\r\n onUpdated,\r\n provide,\r\n watch,\r\n} from 'vue';\r\nimport { useEventListener, useResizeObserver, isNumber } from '@vueuse/core';\r\n\r\nimport { addUnit, isValueNumber, isObject } from '../../utils/helpers';\r\nimport Bar from './bar.vue';\r\n\r\n// ts\r\nimport type { CSSProperties } from 'vue';\r\nimport {\r\n BarInstance,\r\n Props,\r\n Data,\r\n ScrollbarContextKey,\r\n} from './types/scrollbar';\r\n\r\n// top 2 + bottom 2\r\nconst GAP = 4;\r\n\r\nconst prefixCls = 'ivue-scrollbar';\r\n\r\nexport default defineComponent({\r\n name: prefixCls,\r\n emits: ['on-scroll'],\r\n props: {\r\n /**\r\n * 包裹容器的自定义类名\r\n *\r\n * @type {String}\r\n */\r\n wrapperClass: {\r\n type: String,\r\n default: '',\r\n },\r\n /**\r\n * 包裹容器的自定义样式\r\n *\r\n * @type {String | Object}\r\n */\r\n wrapperStyle: {\r\n type: [String, Object],\r\n default: '',\r\n },\r\n /**\r\n * 视图的自定义类名\r\n *\r\n * @type {String}\r\n */\r\n contentClass: {\r\n type: String,\r\n default: '',\r\n },\r\n /**\r\n * 视图的自定义样式\r\n *\r\n * @type {String | Object}\r\n */\r\n contentStyle: {\r\n type: [String, Object],\r\n default: '',\r\n },\r\n /**\r\n * 是否使用原生滚动条样式\r\n *\r\n * @type {Boolean}\r\n */\r\n native: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 滚动条高度\r\n *\r\n * @type {String | Number}\r\n */\r\n height: {\r\n type: [String, Number],\r\n default: '',\r\n },\r\n /**\r\n * 滚动条最大高度\r\n *\r\n * @type {String | Number}\r\n */\r\n maxHeight: {\r\n type: [String, Number],\r\n default: '',\r\n },\r\n /**\r\n * 视图的元素标签\r\n *\r\n * @type {String}\r\n */\r\n tag: {\r\n type: String,\r\n default: 'div',\r\n },\r\n /**\r\n * 滚动条总是显示\r\n *\r\n * @type {Boolean}\r\n */\r\n always: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 不响应容器尺寸变化,如果容器尺寸不会发生变化,最好设置它可以优化性能\r\n *\r\n * @type {Boolean}\r\n */\r\n noresize: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n /**\r\n * 自定义滚动条最小尺寸(开启 native 该属性不生效)\r\n *\r\n * @type {Number}\r\n */\r\n minBarSize: {\r\n type: Number,\r\n default: 20,\r\n },\r\n },\r\n setup(props: Props, { emit }) {\r\n // dom\r\n const scrollbarWrapper = ref<HTMLDivElement>();\r\n const scrollbar = ref<HTMLDivElement>();\r\n const resize = ref<HTMLDivElement>();\r\n\r\n const bar = ref<BarInstance>();\r\n\r\n // data\r\n const data = reactive<Data>({\r\n /**\r\n * 滚动条高度\r\n *\r\n * @type {String}\r\n */\r\n barHeight: '0',\r\n /**\r\n * 滚动条宽度\r\n *\r\n * @type {String}\r\n */\r\n barWidth: '0',\r\n /**\r\n * x轴滚动比率\r\n *\r\n * @type {Number}\r\n */\r\n ratioX: 1,\r\n /**\r\n * y轴滚动比率\r\n *\r\n * @type {Number}\r\n */\r\n ratioY: 1,\r\n });\r\n\r\n // computed\r\n\r\n // 外层样式\r\n const wrapperClasses = computed(() => {\r\n return [\r\n props.wrapperClass,\r\n `${prefixCls}-wrapper`,\r\n {\r\n [`${prefixCls}-hidden-default`]: !props.native,\r\n },\r\n ];\r\n });\r\n\r\n // 外层样式\r\n const wrapperStyles = computed(() => {\r\n const style: CSSProperties = {};\r\n\r\n // 滚动条高度\r\n if (props.height) {\r\n style.height = addUnit(props.height);\r\n }\r\n\r\n // 滚动条最大高度\r\n if (props.maxHeight) {\r\n style.maxHeight = addUnit(props.maxHeight);\r\n }\r\n\r\n return [props.wrapperStyle, style];\r\n });\r\n\r\n // 内容样式\r\n const contentClasses = computed(() => {\r\n return [props.contentClass, `${prefixCls}-content`];\r\n });\r\n\r\n // methods\r\n\r\n // 滚动\r\n const handleScroll = () => {\r\n if (scrollbarWrapper.value) {\r\n bar.value?.handleScroll(scrollbarWrapper.value);\r\n\r\n emit('on-scroll', {\r\n scrollTop: scrollbarWrapper.value.scrollTop,\r\n scrollLeft: scrollbarWrapper.value.scrollLeft,\r\n });\r\n }\r\n };\r\n\r\n // 更新状态\r\n const update = () => {\r\n if (!scrollbarWrapper.value) {\r\n return;\r\n }\r\n\r\n // 表格高度\r\n const offsetHeight = scrollbarWrapper.value.offsetHeight - GAP;\r\n // 可滚动高度\r\n const originalHeight =\r\n offsetHeight ** 2 / scrollbarWrapper.value.scrollHeight;\r\n // 滚动条高度\r\n const height = Math.max(originalHeight, props.minBarSize);\r\n // 滚动条高度\r\n data.barHeight = height + GAP < offsetHeight ? `${height}px` : '';\r\n\r\n // 表格宽度\r\n const offsetWidth = scrollbarWrapper.value.offsetWidth - GAP;\r\n // 滚动条宽度\r\n const originalWidth =\r\n offsetWidth ** 2 / scrollbarWrapper.value.scrollWidth;\r\n\r\n // 表格宽度\r\n const width = Math.max(originalWidth, props.minBarSize);\r\n // 滚动条宽度\r\n data.barWidth = width + GAP < offsetWidth ? `${width}px` : '';\r\n\r\n // x轴滚动比率\r\n data.ratioX =\r\n originalWidth /\r\n (offsetWidth - originalWidth) /\r\n (width / (offsetWidth - width));\r\n\r\n // y轴滚动比率\r\n data.ratioY =\r\n originalHeight /\r\n (offsetHeight - originalHeight) /\r\n (height / (offsetHeight - height));\r\n };\r\n\r\n // 设置滚动高度\r\n const setScrollTop = (value: number) => {\r\n if (!isValueNumber(value)) {\r\n return;\r\n }\r\n\r\n scrollbarWrapper.value.scrollTop = value;\r\n };\r\n\r\n // 设置滚动左右\r\n const setScrollLeft = (value: number) => {\r\n if (!isValueNumber(value)) {\r\n return;\r\n }\r\n\r\n scrollbarWrapper.value.scrollLeft = value;\r\n };\r\n\r\n // 滚动到一组特定坐标\r\n const scrollTo = (arg1: unknown, arg2?: number): void => {\r\n // 对象\r\n if (isObject(arg1)) {\r\n scrollbarWrapper.value.scrollTo(arg1);\r\n }\r\n // 数字\r\n else if (isNumber(arg1) && isNumber(arg2)) {\r\n scrollbarWrapper.value.scrollTo(arg1, arg2);\r\n }\r\n };\r\n\r\n // watch\r\n\r\n // 滚动条高度\r\n watch(\r\n () => props.height,\r\n () => {\r\n if (!props.native) {\r\n nextTick(() => {\r\n update();\r\n\r\n if (scrollbarWrapper.value) {\r\n bar.value?.handleScroll(scrollbarWrapper.value);\r\n }\r\n });\r\n }\r\n }\r\n );\r\n\r\n // 不响应容器尺寸变化,如果容器尺寸不会发生变化,最好设置它可以优化性能\r\n watch(\r\n () => props.noresize,\r\n (value) => {\r\n // 不响应\r\n if (!value) {\r\n // 元素内容或边框尺寸的变化\r\n useResizeObserver(resize.value, update);\r\n\r\n // window resize\r\n useEventListener('resize', update);\r\n }\r\n },\r\n {\r\n immediate: true,\r\n }\r\n );\r\n\r\n // onMounted\r\n onMounted(() => {\r\n if (!props.native) {\r\n nextTick(() => {\r\n update();\r\n });\r\n }\r\n });\r\n\r\n // 数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用\r\n onUpdated(() => {\r\n update();\r\n });\r\n\r\n // provide\r\n provide(\r\n ScrollbarContextKey,\r\n reactive({\r\n scrollbar: scrollbar,\r\n scrollbarWrapper: scrollbarWrapper,\r\n })\r\n );\r\n\r\n return {\r\n prefixCls,\r\n // dom\r\n scrollbarWrapper,\r\n scrollbar,\r\n bar,\r\n resize,\r\n\r\n // data\r\n data,\r\n // computed\r\n wrapperClasses,\r\n wrapperStyles,\r\n contentClasses,\r\n\r\n // methods\r\n handleScroll,\r\n setScrollTop,\r\n setScrollLeft,\r\n update,\r\n scrollTo,\r\n };\r\n },\r\n components: {\r\n Bar,\r\n },\r\n});\r\n</script>\r\n"],"names":["_resolveComponent","_openBlock","_createElementBlock","_normalizeClass","_normalizeStyle","_createBlock","_resolveDynamicComponent","_createCommentVNode"],"mappings":";;;;;yBACEA,iBA2BM,KAAA,CAAA,CAAA;EA3BsB,OAAAC,SAAA,EAAW,EAAAC,kBAAA,CAAA,KAAA,EAAA;AAAA,IAAA,KAAA,EAAAC,cAAA,CAAA,IAAA,CAAA,SAAA,CAAA;AAAA,IACrC,GAAA,EAAA,WAAA;AAAA,GAAA,EAAA;AAAA,uBAEQ,KAAE,EAAA;AAAA,MACP,KAAA,EAAMA,cAAA,CAAA,IAAA,CAAA,cAAA,CAAA;AAAA,MACP,KAAA,EAAIC,cAAkB,CAAA,IAAA,CAAA,aAAA,CAAA;AAAA,MAAA,QAAA,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,YAAA,IAAA,IAAA,CAAA,YAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA;;OAKdH,WAAA,EAAAI,WAAA,CAAEC,uBAAY,CAAA,IAAA,CAAA,GAAA,CAAA,EAAA;AAAA,QACpB,KAAA,EAAIH,cAAQ,CAAA,IAAA,CAAA,cAAA,CAAA;AAAA,QAAA,KAAA,EAAAC,cAAA,CAAA,IAAA,CAAA,YAAA,CAAA;AAAA;;;;;;OAKI,EAAA,CAAA,EAAA,CAAA,OAAA,EAAA,OAAA,CAAA,CAAA;AAAA,OACH,EAAM,CAAA;AAAA,IAAAG,mBACrB,sEAOO,CAAA;AAAA,IANK,CAAA,IAAA,CAAA,MAAA,IAAAN,SAAA,EAAA,EAAEI,YAAK,cAAS,EAAA;AAAA,MACzB,GAAA,EAAA,CAAA;AAAA,MACA,SAAA,EAAQ,KAAM,IAAA,CAAA,SAAA;AAAA,MACd,QAAA,EAAQ,KAAK,IAAA,CAAA,QAAA;AAAA,MACb,QAAQ,IAAA,CAAA,MAAA;AAAA,MACT,MAAA,EAAI,KAAK,IAAA,CAAA,MAAA;AAAA,MAAA,MAAA,EAAA,KAAA,IAAA,CAAA,MAAA;AAAA;;;;;;;;"}