UNPKG

@fesjs/fes-design

Version:
212 lines (206 loc) 7.29 kB
import { defineComponent, ref, computed, onMounted, watch, onBeforeUnmount, resolveComponent, openBlock, createElementBlock, normalizeClass, createElementVNode, normalizeStyle, renderSlot, Fragment, createVNode, createCommentVNode } from 'vue'; import getPrefixCls from '../_util/getPrefixCls'; import { useTheme } from '../_theme/useTheme'; import { pxfy, requestAnimationFrame } from '../_util/utils'; import useResize from '../_util/use/useResize'; import FBar from './bar.js'; import useScrollbar from './useScrollbar'; import { scrollbarProps } from './const'; const prefixCls = getPrefixCls('scrollbar'); var script = defineComponent({ name: 'FScrollbar', components: { FBar }, props: scrollbarProps, emits: ['scroll'], setup(props, _ref) { let { emit } = _ref; useTheme(); const { onUpdate, onScroll, containerRef, ratioX, ratioY, thumbMoveX, thumbMoveY, sizeHeight, sizeWidth, scrollX, scrollXRatio, scrollY, scrollYRatio } = useScrollbar(props); const scrollbarRef = ref(); const contentRef = ref(); const shadowRef = computed(() => { if (typeof props.shadow === 'boolean') { return { x: props.shadow, y: props.shadow }; } return props.shadow; }); const style = computed(() => [props.containerStyle, { height: pxfy(props.height), maxHeight: pxfy(props.maxHeight) }]); const wrapperClassRef = computed(() => [prefixCls]); const containerClassRef = computed(() => [`${prefixCls}-container`, props.containerClass, !props.native && `${prefixCls}-hidden-native-bar`]); const handleScroll = event => { onScroll(); const containerRefValue = containerRef.value; if (containerRefValue) { emit('scroll', event, containerRefValue); } }; // contentRef 为 containerRef 的子元素,所以 containerRef 不需要再监听 useResize(contentRef, () => { onUpdate(); onScroll(); }, computed(() => props.noresize), false); useResize(scrollbarRef, () => { onUpdate(); onScroll(); }, computed(() => props.noresize), false); onMounted(() => { // 等待content插槽内容渲染完毕用setTimeout if (!props.native) { setTimeout(onUpdate, 0); } setTimeout(onScroll, 0); }); watch(() => props.minSize, () => { onUpdate(); onScroll(); }, { immediate: false }); let rafId; const move = (type, to, duration) => { if (!duration || duration <= 0) { containerRef.value[type] = to; return; } const difference = to - containerRef.value[type]; const perTick = difference / duration * 10; rafId = requestAnimationFrame(() => { containerRef.value[type] += perTick; if (containerRef.value[type] === to) { return; } move(type, to, duration - 10); }); }; const setScrollTop = (val, duration) => { move('scrollTop', val, duration); }; const setScrollLeft = (val, duration) => { move('scrollLeft', val, duration); }; const scrollToEnd = (direction, duration) => { if (direction === 'bottom') { move('scrollTop', contentRef.value.offsetHeight, duration); } else if (direction === 'right') { move('scrollLeft', contentRef.value.offsetWidth, duration); } else { move('scrollTop', contentRef.value.offsetHeight, duration); move('scrollLeft', contentRef.value.offsetWidth, duration); } }; onBeforeUnmount(() => { if (rafId) { cancelAnimationFrame(rafId); } }); return { scrollbarRef, containerRef, contentRef, style, prefixCls, setScrollTop, setScrollLeft, scrollToEnd, update: onUpdate, handleScroll, thumbMoveX, thumbMoveY, ratioX, ratioY, sizeHeight, sizeWidth, wrapperClassRef, containerClassRef, scrollX, scrollXRatio, scrollY, scrollYRatio, shadowRef }; } }); function render(_ctx, _cache, $props, $setup, $data, $options) { const _component_FBar = resolveComponent("FBar"); return openBlock(), createElementBlock("div", { ref: "scrollbarRef", class: normalizeClass(_ctx.wrapperClassRef) }, [createElementVNode("div", { ref: "containerRef", class: normalizeClass(_ctx.containerClassRef), style: normalizeStyle(_ctx.style), onScroll: _cache[0] || (_cache[0] = function () { return _ctx.handleScroll && _ctx.handleScroll(...arguments); }) }, [createElementVNode("div", { ref: "contentRef", class: normalizeClass(`${_ctx.prefixCls}-content`), style: normalizeStyle([_ctx.scrollX && { width: 'fit-content' }, _ctx.contentStyle]) }, [renderSlot(_ctx.$slots, "default")], 6 /* CLASS, STYLE */)], 38 /* CLASS, STYLE, NEED_HYDRATION */), !_ctx.native ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createVNode(_component_FBar, { thumbStyle: _ctx.thumbStyle, scrollbarRef: [_ctx.scrollbarRef], containerRef: _ctx.containerRef, move: _ctx.thumbMoveX, ratio: _ctx.ratioX, size: _ctx.sizeWidth, always: _ctx.always, style: normalizeStyle(_ctx.horizontalRatioStyle) }, null, 8 /* PROPS */, ["thumbStyle", "scrollbarRef", "containerRef", "move", "ratio", "size", "always", "style"]), createVNode(_component_FBar, { thumbStyle: _ctx.thumbStyle, scrollbarRef: [_ctx.scrollbarRef], containerRef: _ctx.containerRef, move: _ctx.thumbMoveY, ratio: _ctx.ratioY, size: _ctx.sizeHeight, vertical: "", always: _ctx.always, style: normalizeStyle(_ctx.verticalRatioStyle) }, null, 8 /* PROPS */, ["thumbStyle", "scrollbarRef", "containerRef", "move", "ratio", "size", "always", "style"])], 64 /* STABLE_FRAGMENT */)) : createCommentVNode("v-if", true), _ctx.shadowRef.x && _ctx.scrollX && _ctx.scrollXRatio < 1 ? (openBlock(), createElementBlock("div", { key: 1, class: normalizeClass(`${_ctx.prefixCls}-shadow-right`), style: normalizeStyle(_ctx.shadowStyle) }, null, 6 /* CLASS, STYLE */)) : createCommentVNode("v-if", true), _ctx.shadowRef.x && _ctx.scrollX && _ctx.scrollXRatio > 0 ? (openBlock(), createElementBlock("div", { key: 2, class: normalizeClass(`${_ctx.prefixCls}-shadow-left`), style: normalizeStyle(_ctx.shadowStyle) }, null, 6 /* CLASS, STYLE */)) : createCommentVNode("v-if", true), _ctx.shadowRef.y && _ctx.scrollY && _ctx.scrollYRatio < 1 ? (openBlock(), createElementBlock("div", { key: 3, class: normalizeClass(`${_ctx.prefixCls}-shadow-bottom`), style: normalizeStyle(_ctx.shadowStyle) }, null, 6 /* CLASS, STYLE */)) : createCommentVNode("v-if", true), _ctx.shadowRef.y && _ctx.scrollY && _ctx.scrollYRatio > 0 ? (openBlock(), createElementBlock("div", { key: 4, class: normalizeClass(`${_ctx.prefixCls}-shadow-top`), style: normalizeStyle(_ctx.shadowStyle) }, null, 6 /* CLASS, STYLE */)) : createCommentVNode("v-if", true)], 2 /* CLASS */); } script.render = render; script.__file = "components/scrollbar/scrollbar.vue"; export { script as default };