BackTop.mjs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import { mergeProps as _mergeProps, createVNode as _createVNode } from "vue";
  2. import { ref, watch, computed, Teleport, nextTick, onMounted, defineComponent } from "vue";
  3. import { addUnit, inBrowser, numericProp, getScrollTop, createNamespace, makeNumericProp } from "../utils/index.mjs";
  4. import { throttle } from "../lazyload/vue-lazyload/util.mjs";
  5. import { useEventListener, getScrollParent } from "@vant/use";
  6. import { Icon } from "../icon/index.mjs";
  7. const [name, bem] = createNamespace("back-top");
  8. const backTopProps = {
  9. right: numericProp,
  10. bottom: numericProp,
  11. target: [String, Object],
  12. offset: makeNumericProp(200),
  13. teleport: {
  14. type: [String, Object],
  15. default: "body"
  16. }
  17. };
  18. var stdin_default = defineComponent({
  19. name,
  20. inheritAttrs: false,
  21. props: backTopProps,
  22. emits: ["click"],
  23. setup(props, {
  24. emit,
  25. slots,
  26. attrs
  27. }) {
  28. const show = ref(false);
  29. const root = ref();
  30. const scrollParent = ref();
  31. const style = computed(() => ({
  32. right: addUnit(props.right),
  33. bottom: addUnit(props.bottom)
  34. }));
  35. const onClick = (event) => {
  36. var _a;
  37. emit("click", event);
  38. (_a = scrollParent.value) == null ? void 0 : _a.scrollTo({
  39. top: 0,
  40. behavior: "smooth"
  41. });
  42. };
  43. const scroll = () => {
  44. show.value = scrollParent.value ? getScrollTop(scrollParent.value) >= props.offset : false;
  45. };
  46. const getTarget = () => {
  47. const {
  48. target
  49. } = props;
  50. if (typeof target === "string") {
  51. const el = document.querySelector(target);
  52. if (el) {
  53. return el;
  54. }
  55. if (process.env.NODE_ENV !== "production") {
  56. console.error(`[Vant] BackTop: target element "${target}" was not found, the BackTop component will not be rendered.`);
  57. }
  58. } else {
  59. return target;
  60. }
  61. };
  62. const updateTarget = () => {
  63. if (inBrowser) {
  64. nextTick(() => {
  65. scrollParent.value = props.target ? getTarget() : getScrollParent(root.value);
  66. scroll();
  67. });
  68. }
  69. };
  70. useEventListener("scroll", throttle(scroll, 100), {
  71. target: scrollParent
  72. });
  73. onMounted(updateTarget);
  74. watch(() => props.target, updateTarget);
  75. return () => {
  76. const Content = _createVNode("div", _mergeProps({
  77. "ref": root,
  78. "class": bem({
  79. active: show.value
  80. }),
  81. "style": style.value,
  82. "onClick": onClick
  83. }, attrs), [slots.default ? slots.default() : _createVNode(Icon, {
  84. "name": "back-top",
  85. "class": bem("icon")
  86. }, null)]);
  87. if (props.teleport) {
  88. return _createVNode(Teleport, {
  89. "to": props.teleport
  90. }, {
  91. default: () => [Content]
  92. });
  93. }
  94. return Content;
  95. };
  96. }
  97. });
  98. export {
  99. backTopProps,
  100. stdin_default as default
  101. };