UNPKG

element-plus

Version:

A Component Library for Vue3.0

117 lines (110 loc) 3.83 kB
import { defineComponent, ref, computed, onMounted, onBeforeUnmount, openBlock, createBlock, Transition, withCtx, withModifiers, renderSlot, createCommentVNode, createVNode } from 'vue'; import throttle from 'lodash/throttle'; import { on, off } from '../utils/dom'; import { easeInOutCubic } from '../utils/animation'; var script = defineComponent({ name: 'ElBacktop', props: { visibilityHeight: { type: Number, default: 200, }, target: { type: String, default: '', }, right: { type: Number, default: 40, }, bottom: { type: Number, default: 40, }, }, emits: ['click'], setup(props, ctx) { const el = ref(null); const container = ref(null); const visible = ref(false); const styleBottom = computed(() => `${props.bottom}px`); const styleRight = computed(() => `${props.right}px`); const scrollToTop = () => { const beginTime = Date.now(); const beginValue = el.value.scrollTop; const rAF = window.requestAnimationFrame || (func => setTimeout(func, 16)); const frameFunc = () => { const progress = (Date.now() - beginTime) / 500; if (progress < 1) { el.value.scrollTop = beginValue * (1 - easeInOutCubic(progress)); rAF(frameFunc); } else { el.value.scrollTop = 0; } }; rAF(frameFunc); }; const onScroll = () => { visible.value = el.value.scrollTop >= props.visibilityHeight; }; const handleClick = event => { scrollToTop(); ctx.emit('click', event); }; const throttledScrollHandler = throttle(onScroll, 300); onMounted(() => { container.value = document; el.value = document.documentElement; if (props.target) { el.value = document.querySelector(props.target); if (!el.value) { throw new Error(`target is not existed: ${props.target}`); } container.value = el.value; } on(container.value, 'scroll', throttledScrollHandler); }); onBeforeUnmount(() => { off(container.value, 'scroll', throttledScrollHandler); }); return { el, container, visible, styleBottom, styleRight, handleClick, }; }, }); const _hoisted_1 = /*#__PURE__*/createVNode("i", { class: "el-icon-caret-top" }, null, -1 /* HOISTED */); function render(_ctx, _cache, $props, $setup, $data, $options) { return (openBlock(), createBlock(Transition, { name: "el-fade-in" }, { default: withCtx(() => [ (_ctx.visible) ? (openBlock(), createBlock("div", { key: 0, style: { 'right': _ctx.styleRight, 'bottom': _ctx.styleBottom }, class: "el-backtop", onClick: _cache[1] || (_cache[1] = withModifiers((...args) => (_ctx.handleClick && _ctx.handleClick(...args)), ["stop"])) }, [ renderSlot(_ctx.$slots, "default", {}, () => [ _hoisted_1 ]) ], 4 /* STYLE */)) : createCommentVNode("v-if", true) ]), _: 1 /* STABLE */ })) } script.render = render; script.__file = "packages/backtop/src/index.vue"; script.install = (app) => { app.component(script.name, script); }; const _Backtop = script; export default _Backtop;